Elasticsearch 6.8.8多字段自动补全:如何先按Key再按Value搜索?
解决方案:关联Key和Value的Completion Suggest搜索
你的问题核心是当前的两个suggest是独立执行的,没有关联关系——它们各自在全量文档里做前缀匹配,而不是先限定Key的范围再搜对应的Value。下面给你两种适配Elasticsearch 6.8.8的实现方案:
方案一:分两次请求(简单易实现)
这种方式逻辑清晰,不需要修改现有mapping,适合快速落地:
第一步:获取匹配的Key列表
先发起请求,用keySuggester得到符合前缀的Key结果:
{ "suggest": { "key_suggest": { "prefix": "Something1", "completion": { "field": "keySuggester", "fuzzy": true, "size": 20 } } } }
从返回结果中提取所有匹配的Key值(比如["KeyA", "KeyB", ...])。
第二步:基于匹配的Key搜索对应的Value
把第一步拿到的Key列表作为过滤条件,再发起Value的suggest请求:
{ "query": { "terms": { "key": ["KeyA", "KeyB"] // 替换成第一步得到的Key列表 } }, "suggest": { "value_suggest": { "prefix": "Something2", "completion": { "field": "valueSuggester", "fuzzy": true, "size": 20 } } } }
这里的query会先过滤出Key匹配的文档,suggest只在这些文档里做Value的前缀模糊匹配,完美实现你要的"先搜Key再关联Value"的效果。
方案二:用上下文Completion Suggester(单请求完成)
如果希望用一个请求完成关联搜索,可以给valueSuggester添加Key上下文约束,不过需要先修改你的mapping:
第一步:更新Mapping
给valueSuggester配置基于key字段的分类上下文:
PUT /your_index_name/_mapping/_doc { "properties": { "key": { "type": "keyword" }, "value": { "type": "keyword" }, "keySuggester": { "type": "completion" }, "valueSuggester": { "type": "completion", "contexts": [ { "name": "key_context", "type": "category", "path": "key" // 关联到文档的key字段 } ] } } }
更新后需要重新索引现有文档,让上下文生效。
第二步:发起关联搜索请求
先通过key_suggest得到匹配的Key,再把这些Key的前缀作为上下文参数传给value_suggest:
{ "suggest": { "key_suggest": { "prefix": "Something1", "completion": { "field": "keySuggester", "fuzzy": true, "size": 20 } }, "value_suggest": { "prefix": "Something2", "completion": { "field": "valueSuggester", "fuzzy": true, "size": 20, "contexts": { "key_context": [ {"prefix": "Something1", "fuzzy": true} // 直接用Key的前缀做上下文过滤 ] } } } } }
这里的value_suggest会自动只考虑Key前缀匹配"Something1"的文档,一次请求就能得到关联结果。
两种方案各有优劣:方案一无需修改mapping,适合现有系统快速调整;方案二用单请求完成,效率更高,但需要修改索引结构并重新索引。你可以根据自己的场景选择。
内容的提问来源于stack exchange,提问作者SolarCore
相关产品推荐
相关产品推荐

