在NEST
中,可以对所有属性或者指定属性进行映射转换。
.AutoMap()
方法内部实现了访问者模式,默认的访问者是NoopPropertyVisitor
,它只提供了一个空白的访问者实现,并没有任何方法,这样你可以允许你实现自已的访问者方法。
在以下示例中,将创建一个禁用文档数字和布尔值的访问者类—这可能不符合实际应用程序的场景,仅仅为了示例。
先定义一个Employee
的实体类:
public class Employee
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Salary { get; set; }
public DateTime Birthday { get; set; }
public bool IsManager { get; set; }
public List<Employee> Employees { get; set; }
public TimeSpan Hours { get; set; }
}
在创建一个自定义的访问者类DisableDocValuePropertyVisitor
,它继承自NoopPropertyVisitor
,并重写Visit
方法:
public class DisableDocValuesPropertyVisitor : NoopPropertyVisitor
{
public override void Visit(
INumberProperty type,
PropertyInfo propertyInfo,
ElasticsearchPropertyAttributeBase attribute)
{
type.DocValues = false; // 重写INumberProperty参数的Visit方法,以禁用文档的数字
}
public override void Visit(
IBooleanProperty type,
PropertyInfo propertyInfo,
ElasticsearchPropertyAttributeBase attribute)
{
type.DocValues = false; // 重写IBooleanProperty参数的Visit方法,以禁用文档的布尔值
}
}
现在使用自定义的访问者DisableDocValuePropertyVisitor
来进行映射:
var createIndexResponse = client.Indices.Create("myindex", c => c
.Map<Employee>(m => m.AutoMap(new DisableDocValuesPropertyVisitor()))
);
以后在进行实体(本例为Employee
)的任何属性映射时,只要是数字或者布尔值的属性,doc_values
都将被映射成禁用状态,如下:
{
"mappings": {
"properties": {
"birthday": {
"type": "date"
},
"employees": {
"properties": {},
"type": "object"
},
"firstName": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"isManager": {
"doc_values": false,
"type": "boolean"
},
"lastName": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"salary": {
"doc_values": false,
"type": "integer"
},
"hours": {
"doc_values": false,
"type": "long"
}
}
}
}
访问PropertyInfo
属性
NEST
重写访问者时,还可以直接访问PropertyInfo
属性,而不是访问IProperty
类型。
比如,下面这个示例将所有CLR类型映射成了Elasticsearch中的text
类型:
public class EverythingIsATextPropertyVisitor : NoopPropertyVisitor
{
public override IProperty Visit(PropertyInfo propertyInfo, ElasticsearchPropertyAttributeBase attribute) => new TextProperty();
}
var createIndexResponse = client.Indices.Create("myindex", c => c
.Map<Employee>(m => m.AutoMap(new EverythingIsATextPropertyVisitor()))
);
{
"mappings": {
"properties": {
"birthday": {
"type": "text"
},
"employees": {
"type": "text"
},
"firstName": {
"type": "text"
},
"isManager": {
"type": "text"
},
"lastName": {
"type": "text"
},
"salary": {
"type": "text"
},
"hours": {
"type": "text"
}
}
}
}
跳过某些属性的映射
通过在访问者上实现SkipProperty
,可以防止某些属性被映射。在以下示例中,将跳过派生自DictionaryDocument
的类型的继承属性:
public class DictionaryDocument : SortedDictionary<string, dynamic>
{
public int Id { get; set; }
}
public class IgnoreInheritedPropertiesVisitor<T> : NoopPropertyVisitor
{
public override bool SkipProperty(PropertyInfo propertyInfo, ElasticsearchPropertyAttributeBase attribute)
{
return propertyInfo?.DeclaringType != typeof(T);
}
}
var createIndexResponse = client.Indices.Create("myindex", c => c
.Map<DictionaryDocument>(m => m.AutoMap(new IgnoreInheritedPropertiesVisitor<DictionaryDocument>()))
);
{
"mappings": {
"properties": {
"id": {
"type": "integer"
}
}
}
}
发表评论
登录用户才能发表评论, 请 登 录 或者 注册