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



我想使用 Nest 在 C# 中动态映射 JObject 中的属性。 目标是将对象的每个字符串字段映射为 SearchAsYouType。 我想到了 3 种不起作用的方法:

  1. 使用自动映射并直接在 C# 类中声明属性
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.使用动态模板,但我在映射中找不到搜索,似乎它在 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.使用访问者强制每个字符串都是搜索你输入

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.使用动态模板,但我在映射中找不到 SearchAsYouType,似乎它在 Nest 7.4.1 中还不存在

你是对的,看起来它SingleMappingSelector中缺少,但您可以使用此扩展类轻松解决它,该扩展类将添加对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"
}
}
}
}
}
}
}

这是GH问题。

希望有帮助。

最新更新