我们正在使用ElasticSearch 5。
我有一个字段city
使用自定义分析器和以下映射。
分析仪
"analysis": {
"analyzer": {
"lowercase_analyzer": {
"filter": [
"standard",
"lowercase",
"trim"
],
"type": "custom",
"tokenizer": "keyword"
}
}
映射
"city": {
"type": "text",
"analyzer": "lowercase_analyzer"
}
我这样做,以便我可以对城市字段进行不区分大小写的排序。这是我尝试运行的示例查询
{
"query": {
"term": {
"email": {
"value": "some_email@test.com"
}
}
},
"sort": [
{
"city": {
"order": "desc"
}
}
]
}
以下是我遇到的错误:
"默认情况下,文本字段禁用Fielddata。设置fielddata = true 在[city]上通过uninverting来加载内存中的fielddata 倒指数。请注意,这可能会占用大量内存。"
我不想打开FieldData
并在ElasticSearch中产生性能影响。我希望Keyword
字段不区分大小写,以便我可以对其执行更有意义的聚合和排序。有没有办法做到这一点?
答案 0 :(得分:2)
是的,有一种方法可以使用multi_fields
。
在Elasticsearch 5.0之后,string
field types were split out分为两种不同的类型,text
字段类型,经过分析并可用于搜索,以及keyword
字段类型未分析且适合用于排序,聚合和精确值匹配。
使用Elasticsearch 5.0中的动态映射(即让Elasticsearch推断应该将文档属性映射到的类型),将json string
属性映射到text
字段类型,并使用子字段"关键字"它被映射为keyword
字段类型和设置ignore_above:256
。
使用NEST 5.x自动化,POCO上的string
属性将被自动化,就像Elasticsearch中的动态映射按上述方式映射它一样。鉴于以下文件
public class Document
{
public string Property { get; set; }
}
var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
var defaultIndex = "default-index";
var connectionSettings = new ConnectionSettings(pool)
.DefaultIndex(defaultIndex);
var client = new ElasticClient(connectionSettings);
client.CreateIndex(defaultIndex, c => c
.Mappings(m => m
.Map<Document>(mm => mm
.AutoMap()
)
)
);
产生
{
"mappings": {
"document": {
"properties": {
"property": {
"fields": {
"keyword": {
"ignore_above": 256,
"type": "keyword"
}
},
"type": "text"
}
}
}
}
}
您现在可以使用property
使用Field(f => f.Property.Suffix("keyword")
进行排序。有关更多示例,请查看Field Inference。
keyword
字段类型默认启用doc_values
,这意味着在索引时构建了一个列式数据结构,这就是提供有效排序和聚合的方法。
要在索引创建时添加自定义分析器,我们可以像以前一样自动执行,但随后为我们要控制.Properties()
的映射的字段提供覆盖
client.CreateIndex(defaultIndex, c => c
.Settings(s => s
.Analysis(a => a
.Analyzers(aa => aa
.Custom("lowercase_analyzer", ca => ca
.Tokenizer("keyword")
.Filters(
"standard",
"lowercase",
"trim"
)
)
)
)
)
.Mappings(m => m
.Map<Document>(mm => mm
.AutoMap()
.Properties(p => p
.Text(t => t
.Name(n => n.Property)
.Analyzer("lowercase_analyzer")
.Fields(f => f
.Keyword(k => k
.Name("keyword")
.IgnoreAbove(256)
)
)
)
)
)
)
);
产生
{
"settings": {
"analysis": {
"analyzer": {
"lowercase_analyzer": {
"type": "custom",
"filter": [
"standard",
"lowercase",
"trim"
],
"tokenizer": "keyword"
}
}
}
},
"mappings": {
"document": {
"properties": {
"property": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
},
"analyzer": "lowercase_analyzer"
}
}
}
}
}