如何使用 Elasticsearch Nest 在 C# 中动态映射 JObject 的属性

How to Map dynamically the properties of a JObject in C# using Elasticsearch Nest

我想使用 Nest 在 C# 中动态映射 JObject 中的属性。 目标是将对象的每个字符串字段映射为 SearchAsYouType。 我考虑了 3 种方法,但都行不通:

  1. 使用 AutoMap 并直接在 C# 中声明属性Class
public class Forfait
    {
        public long Id { get; set; }
        [SearchAsYouType()] 
        public string Data { get; set; }
    }
public class  Act
    {
        public JObject Entity;
    }
Forfait forfait = new Forfait()
            {
                Data = "data",
                Id = 99
            };
            Act act = new Act()
            {
                Entity = JObject.FromObject(forfait)
            };

            await client.Indices.CreateAsync("index", o => o
                .Map<Act>(m => m
                .AutoMap()

2.Use DynamicTemplates 但我在映射中找不到 SearchAsYouType,它似乎在 Nest 7.4.1 中还不存在

await client.Indices.CreateAsync("index", o => o
                .Map<Act>(m => m
                .DynamicTemplates(d =>d
                    .DynamicTemplate("stringassearch",dt => dt
                        .Match("entity.*")
                        .MatchMappingType("string")
                        .Mapping(ma =>ma
                            .)))));

3.Use 访问者强制每个字符串成为 SearchAsYouType

public class EveryStringIsASearchAsYouTypePropertyVisitor : NoopPropertyVisitor
    {
        public override IProperty Visit(PropertyInfo propertyInfo, ElasticsearchPropertyAttributeBase attribute)
        {
            if (propertyInfo.PropertyType == typeof(String))
                return new SearchAsYouTypeProperty();
            return null;
        }
    }
await client.Indices.CreateAsync("index", o => o
                .Map<Act>(m => m
                .AutoMap(new EveryStringIsASearchAsYouTypePropertyVisitor(),2)

一切都失败了

我觉得解决方案是 NEST.JsonNetSerializer 以某种方式使映射中使用的设置在 JObject 中应用,但我找不到任何有用的东西

2.Use DynamicTemplates but i can't find SearchAsYouType in the Mapping, it seems that it doesn't exist in Nest 7.4.1 yet

你是对的,看起来 SingleMappingSelector 中缺少它,但你可以使用此扩展 class 轻松解决它,它将添加对 search_as_you_type 类型的支持。

static class MappingExtension
{
    public static IProperty SearchAsYouType<T>(this SingleMappingSelector<T> mappingSelector, 
        Func<SearchAsYouTypePropertyDescriptor<T>, ISearchAsYouTypeProperty> selector) where T : class
    => selector?.Invoke(new SearchAsYouTypePropertyDescriptor<T>());
} 

然后您可以按照以下方式创建动态模板

var createIndexResponse = await client.Indices.CreateAsync("index", o => o
    .Map<Act>(m => m
        .AutoMap<Act>()
        .DynamicTemplates(d => d
            .DynamicTemplate("stringassearch", dt => dt
                .PathMatch("entity.*")
                .MatchMappingType("string")
                .Mapping(ma => ma.SearchAsYouType(s => s))))));

请注意,我已将 Match(..) 更改为 PathMatch(..) - 我认为这就是您所需要的。另外,我必须将 Act 定义更改为

public class  Act
{
    public object Entity;
}

索引示例文档后创建了此索引映射

{
  "index": {
    "mappings": {
      "dynamic_templates": [
        {
          "stringassearch": {
            "path_match": "entity.*",
            "match_mapping_type": "string",
            "mapping": {
              "type": "search_as_you_type"
            }
          }
        }
      ],
      "properties": {
        "entity": {
          "properties": {
            "data": {
              "type": "search_as_you_type",
              "max_shingle_size": 3
            },
            "id": {
              "type": "long"
            }
          }
        }
      }
    }
  }
}

Here是GH问题。

希望对您有所帮助。