给定包含具有 品牌 属性的文档的索引,我们需要创建不区分大小写的术语聚合。
索引定义
请注意,使用 fielddata
PUT demo_products { "settings": { "analysis": { "analyzer": { "my_custom_analyzer": { "type": "custom", "tokenizer": "keyword", "filter": [ "lowercase" ] } } } }, "mappings": { "product": { "properties": { "brand": { "type": "text", "analyzer": "my_custom_analyzer", "fielddata": true, } } } } }
数据
POST demo_products/product { "brand": "New York Jets" } POST demo_products/product { "brand": "new york jets" } POST demo_products/product { "brand": "Washington Redskins" }
询问
GET demo_products/product/_search { "size": 0, "aggs": { "brand_facet": { "terms": { "field": "brand" } } } }
结果
"aggregations": { "brand_facet": { "doc_count_error_upper_bound": 0, "sum_other_doc_count": 0, "buckets": [ { "key": "new york jets", "doc_count": 2 }, { "key": "washington redskins", "doc_count": 1 } ] } }
如果使用keyword而不是,text由于机壳的差异,我们最终要为纽约喷气机找到2个水桶。
keyword
text
我们担心使用字段数据会影响性能。但是,如果禁用了fielddata,我们将得到可怕的 “默认情况下在文本字段上禁用Fielddata”。
还有其他解决此问题的技巧-还是我们不应该太在意fielddate?
从ES 5.2(今天起)开始,可以对字段使用规范化器,keyword以便(例如)将值小写。
规范化器的作用有点像text字段分析器,尽管您可以用它们做些限制,但是这可能会帮助您解决所面临的问题。
您可以这样创建索引:
PUT demo_products { "settings": { "analysis": { "normalizer": { "my_normalizer": { "type": "custom", "filter": [ "lowercase" ] } } } }, "mappings": { "product": { "properties": { "brand": { "type": "keyword", "normalizer": "my_normalizer" } } } } }
您的查询将返回以下内容:
"aggregations" : { "brand_facet" : { "doc_count_error_upper_bound" : 0, "sum_other_doc_count" : 0, "buckets" : [ { "key" : "new york jets", "doc_count" : 2 }, { "key" : "washington redskins", "doc_count" : 1 } ] } }
两全其美!