如何在ElasticSearch索引所有字段中检索匹配关键词
原有查询失效原因
你的写法存在两个明确问题,导致查询无法生效:
match_all是无参查询,作用是返回索引内全部文档,不支持传入检索关键词参数,你传入的"Default"参数会被ElasticSearch直接忽略- 查询指定的索引名是
cfitems-*,和你实际创建的索引名cf_items命名不匹配,请求根本不会命中目标索引
跨任意字段检索关键词的正确实现方案
结合你当前的索引mapping配置,有两种可落地的实现方式:
方案1:使用multi_match实现全字段检索(无需改索引配置,即取即用)
multi_match是ElasticSearch原生支持的跨字段检索语法,将检索字段设为*即可自动遍历所有支持文本检索的字段匹配关键词,自动跳过lastChangeDateTime这类不支持全文检索的日期类型字段,完全适配你当前的索引结构。
以检索关键词Default为例,对应PHP数组格式的查询写法如下:
[ "index" => "cf_items", // 注意和实际索引名保持一致 "body" => [ "query" => [ "multi_match" => [ "query" => "Default", // 替换为实际要检索的关键词 "fields" => ["*"], "type" => "best_fields" ] ] ] ]
- 如果不需要精确匹配未分词的完整值,可以通过减号排除所有keyword子字段提升检索效率,把
fields参数改成["*", "-*.keyword"]即可 - 如果需要同时支持分词模糊匹配和完整值精确匹配,把
fields参数改成["*", "*.keyword"]即可
方案2:配置copy_to自定义全字段(适合高频全字段检索场景,性能更优)
如果全字段检索是业务高频操作,可以修改索引mapping,通过copy_to参数把所有需要参与检索的字段值自动聚合到一个自定义的专用检索字段(比如命名为all_content),检索时直接查询这一个字段即可,性能比遍历全字段更高。
注意:该方案需要修改mapping,必须重建索引才能生效
对应mapping配置片段示例:
{ "properties": { "CFItemType": { "type": "text", "fields": {"keyword": {"type": "keyword", "ignore_above": 256}}, "copy_to": "all_content" }, "fullStatement": { "type": "text", "fields": {"keyword": {"type": "keyword", "ignore_above": 256}}, "copy_to": "all_content" }, // 其余所有需要参与全字段检索的字段都按上述规则添加copy_to配置 "all_content": { "type": "text" } } }
配置完成后,全字段检索可以直接用普通match查询实现:
[ "index" => "cf_items", "body" => [ "query" => [ "match" => [ "all_content" => "Default" ] ] ] ]
注意事项
- 不建议用
query_string做全字段检索,容易出现语法解析错误,且存在注入风险 - 如果需要做模糊匹配、前缀匹配等特殊检索,直接在
multi_match或match查询中添加对应参数即可,不需要调整字段配置
内容的提问来源于stack exchange,提问作者Bhumi Shah
相关产品推荐
相关产品推荐

