我正在做我的自动完成项目,这是Elasticsearch的新项目。我已使用Edge NGram过滤器进行自动补全。
我试图获得自动完成的唯一结果,所以我对所有字段都使用了术语汇总。
对于具有1个值的字段,我得到了很好的结果,但是对于具有多个值的字段,我得到了很好的结果..如果查询与该字段中的至少一个值匹配..它为我提供了该字段的所有值(无论查询是否匹配其他值)。
我在服装索引下的设置和映射是:
PUT /garments
{
"settings" :
{
"number_of_replicas": 3,
"number_of_shards": 2,
"analysis":
{
"analyzer":
{
"autocomplete":
{
"tokenizer": "autocomplete",
"filter":
[
"lowercase"
]
},
"autocomplete_search":
{
"tokenizer": "lowercase"
}
},
"tokenizer":
{
"autocomplete":
{
"type": "edge_ngram",
"min_gram": 2,
"max_gram": 10,
"token_chars":
[
"letter"
]
}
}
}
},
"mappings":
{
"properties":
{
"color":
{
"type": "text",
"analyzer": "autocomplete",
"search_analyzer": "autocomplete_search",
"fields":
{
"keyword":
{
"type": "keyword"
}
}
}
........
........
........
}
}
(请注意我正在使用文本类型)
假设我在文档中有一个颜色字段,该字段具有多个值,如:[“” blue“,” black“,” orange“,” marble“,” jet black“]
我的搜索查询是:
GET /garments/_search
{
"size": 0,
"query":
{
"query_string": {
"query": "bl"
}
},
"aggs":
{
"Term_aggregation":
{
"terms":
{
"field": "color.keyword",
"size": 100
}
}
}
}
这给了我所有的输出,即:“蓝色”,“黑色”,“橙色”,“大理石”,“黑色”。
但是我只想将蓝色,黑色,黑色作为结果(查询为“bl”)。
后来
我用了
"include": " .*bl.*"
用我的话说是滤镜aggs ..这给了我蓝色,黑色,大理石,深黑色作为结果。.包括滤镜是区分大小写的...请帮助!
最佳答案
如果要对关键字字段进行不区分大小写的匹配,则可以将normalizer与小写过滤器一起使用
The normalizer property of keyword fields is similar to analyzer except that it guarantees that the analysis chain produces a single token.
{
"settings": {
"analysis": {
"normalizer": {
"lowercase_normalizer": {
"type": "custom",
"filter": [
"lowercase"
]
}
}
}
},
"mappings": {
"properties": {
"color": {
"type": "text",
"analyzer": "autocomplete",
"search_analyzer": "autocomplete_search",
"fields": {
"keyword": {
"type": "keyword",
"normalizer": "lowercase_normalizer"
}
}
}
}
}
}
“include”:“.bl。”即使实际值包含大写字母也可以使用
编辑1
根据您的评论,如果您不想在术语中使用包含。您需要使用nested type索引颜色,以便将每种颜色都视为单独的对象
对应:
PUT index64
{
"settings": {
"number_of_replicas": 3,
"number_of_shards": 2,
"analysis": {
"analyzer": {
"autocomplete": {
"tokenizer": "autocomplete",
"filter": [
"lowercase"
]
},
"autocomplete_search": {
"tokenizer": "lowercase"
}
},
"tokenizer": {
"autocomplete": {
"type": "edge_ngram",
"min_gram": 2,
"max_gram": 10,
"token_chars": [
"letter"
]
}
}
}
},
"mappings": {
"properties": {
"color": {
"type": "nested",
"properties": {
"name": {
"type": "text",
"analyzer": "autocomplete",
"search_analyzer": "autocomplete_search",
"fields": {
"keyword": {
"type": "keyword"
}
}
}
}
}
}
}
}
查询:
POST index64/_doc
{
"color": [
{
"name": "blue"
},
{
"name": "black"
},
{
"name": "orange"
},
{
"name": "marble"
},
{
"name": "jet black"
}
]
}
结果:
GET index64/_search
{
"size": 0,
"aggs": {
"color": {
"nested": {
"path": "color"
},
"aggs": {
"select_color": {
"filter": {
"match":{
"color.name":"bl"
}
},
"aggs": {
"distinct_colors": {
"terms": {
"field": "color.name.keyword",
"size": 10
}
}
}
}
}
}
}
}
结果
"aggregations" : {
"color" : {
"doc_count" : 5,
"select_color" : {
"doc_count" : 3,
"distinct_colors" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : "black",
"doc_count" : 1
},
{
"key" : "blue",
"doc_count" : 1
},
{
"key" : "jet black",
"doc_count" : 1
}
]
}
}
}
}
关于elasticsearch - 如何使用NGram过滤器自动完成对多值字段的Elasticsearch术语聚合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61949730/