如何将单个 .NET 类型映射到 ElasticSearch/NEST 中的多个嵌套对象类型?
How do I map a single .NET type to multiple nested object types in ElasticSearch/NEST?
我正在使用 NEST 库与 ElasticSearch 交互,我正在尝试找出一种方法来基于非类型数据构建索引 types/nested 对象。该类型具有以下基本结构。
public class Entity : DynamicObject
{
public string Id { get; set; }
// a bunch of other simple properties
public override IEnumerable<string> GetDynamicMemberNames()
{
return Data.Select(x => x.Name);
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
var dictionary = Data.First(x => x.Name == binder.Name);
result = dictionary;
return true;
}
// each instance of one these should be a nested object type
public IList<NestedType> Data { get; set; }
public class NestedType
{
// How do I make Name be the nest type name?
public string Name { get; set; }
public IDictionary<string, string> Values { get; set; }
}
}
我想为 NestedType 的每个实例创建一个嵌套的 object/type。因此,如果有两个 NestedType 实例,那么就会有两个嵌套对象。我可以从 DynamicObject 继承 NestedType 以将字典转换为 "real" 属性,然后 NEST 可以正确映射这些属性(即将每个字典键转换为 属性)。问题是我不知道如何设置嵌套对象的 name/type。
我知道有两种映射名称的方法:ElasticType 属性和 NestedObject 流畅接口。这里的问题是有一个类型表示多个嵌套对象类型。我可以做一些运行时类型构建,但如果可以避免,我宁愿不做。
有没有办法让方法或 属性 用作嵌套对象的 name/type?或者是否有更好的方法将此类数据映射到 ElasticSearch(希望通过 NEST)?
谢谢!
埃里克
编辑
我更新了实体定义以反映我正在做的事情(使用 DynamicObject 让 JsonSerializer 做我想做的事情)。我想要的是不同词典具有不同映射的能力(不同的词干提取、分析器等)。如果有合适的类型,我可以使用 NEST fluent syntax 来设置它,但是当使用 dynamic 时,没有 fluent API 可以使用的类型。最终,我想将流利的 API 与基于字符串而不是类型的字符串混合。这有意义吗?
如果我没理解错你的意图,Entity
对象将只有嵌套对象,不是吗?
您可以尝试对实体对象使用elasticsearch的dynamic mapping功能。我假设 Entity 是根对象。
curl -X POST localhost:9200/myindex/entity/_mapping
{"dynamic_templates": [
{"nested_data_template": {
"mapping": {
"type": "nested" },
"match_mapping_type": "object",
"path_match": "*" }}]}
path_match: *
和 match_mapping_type: object
意味着对于所有以对象为值的字段名称,将应用嵌套类型映射。
使用 NEST 和 Fluent API 您可以使用以下 API。 IntelliSense 将指导您如何在上面构建映射。 ;)
descriptor.DynamicTemplates(DynamicTemplatesDescriptor<Entity>)
每次出现新的属性匹配该模板时,elasticsearch会根据动态映射更新映射。一段时间后,您的映射将如下所示:
{
"entity": {
"mappings": {
"entity": {
"dynamic_templates": [
{
"nested_data_template": {
"mapping": {
"type": "nested"
},
"match_mapping_type": "object",
"path_match": "*"
}
}
],
"properties": {
"test": {
"type": "nested",
"properties": {
"test": {
"type": "string"
},
"another_property": {
"type": "string"
}
}
},
"test1": {
"type": "nested",
"properties": {
"test": {
"type": "string"
}
}
}
}
}
}
}
}
希望这会有所帮助!
我正在使用 NEST 库与 ElasticSearch 交互,我正在尝试找出一种方法来基于非类型数据构建索引 types/nested 对象。该类型具有以下基本结构。
public class Entity : DynamicObject
{
public string Id { get; set; }
// a bunch of other simple properties
public override IEnumerable<string> GetDynamicMemberNames()
{
return Data.Select(x => x.Name);
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
var dictionary = Data.First(x => x.Name == binder.Name);
result = dictionary;
return true;
}
// each instance of one these should be a nested object type
public IList<NestedType> Data { get; set; }
public class NestedType
{
// How do I make Name be the nest type name?
public string Name { get; set; }
public IDictionary<string, string> Values { get; set; }
}
}
我想为 NestedType 的每个实例创建一个嵌套的 object/type。因此,如果有两个 NestedType 实例,那么就会有两个嵌套对象。我可以从 DynamicObject 继承 NestedType 以将字典转换为 "real" 属性,然后 NEST 可以正确映射这些属性(即将每个字典键转换为 属性)。问题是我不知道如何设置嵌套对象的 name/type。
我知道有两种映射名称的方法:ElasticType 属性和 NestedObject 流畅接口。这里的问题是有一个类型表示多个嵌套对象类型。我可以做一些运行时类型构建,但如果可以避免,我宁愿不做。
有没有办法让方法或 属性 用作嵌套对象的 name/type?或者是否有更好的方法将此类数据映射到 ElasticSearch(希望通过 NEST)?
谢谢! 埃里克
编辑
我更新了实体定义以反映我正在做的事情(使用 DynamicObject 让 JsonSerializer 做我想做的事情)。我想要的是不同词典具有不同映射的能力(不同的词干提取、分析器等)。如果有合适的类型,我可以使用 NEST fluent syntax 来设置它,但是当使用 dynamic 时,没有 fluent API 可以使用的类型。最终,我想将流利的 API 与基于字符串而不是类型的字符串混合。这有意义吗?
如果我没理解错你的意图,Entity
对象将只有嵌套对象,不是吗?
您可以尝试对实体对象使用elasticsearch的dynamic mapping功能。我假设 Entity 是根对象。
curl -X POST localhost:9200/myindex/entity/_mapping
{"dynamic_templates": [
{"nested_data_template": {
"mapping": {
"type": "nested" },
"match_mapping_type": "object",
"path_match": "*" }}]}
path_match: *
和 match_mapping_type: object
意味着对于所有以对象为值的字段名称,将应用嵌套类型映射。
使用 NEST 和 Fluent API 您可以使用以下 API。 IntelliSense 将指导您如何在上面构建映射。 ;)
descriptor.DynamicTemplates(DynamicTemplatesDescriptor<Entity>)
每次出现新的属性匹配该模板时,elasticsearch会根据动态映射更新映射。一段时间后,您的映射将如下所示:
{
"entity": {
"mappings": {
"entity": {
"dynamic_templates": [
{
"nested_data_template": {
"mapping": {
"type": "nested"
},
"match_mapping_type": "object",
"path_match": "*"
}
}
],
"properties": {
"test": {
"type": "nested",
"properties": {
"test": {
"type": "string"
},
"another_property": {
"type": "string"
}
}
},
"test1": {
"type": "nested",
"properties": {
"test": {
"type": "string"
}
}
}
}
}
}
}
}
希望这会有所帮助!