Elasticsearch多索引多字段搜索仅返回单索引结果问题排查
问题原因
- 第一版查询的问题:跨多索引查询时,不同索引的字段映射相互独立,
items-123-*索引不存在type字段、asso-456-*索引不存在title字段,不存在字段的匹配条件会直接判定为不匹配,最终只会返回命中自身存在字段的单索引结果。 - 第二版查询的问题:bool查询的每个子句必须是独立的合法查询类型,直接把
term和match_phrase平级放在should子项里属于非法查询结构,ES无法正确解析让两个条件同时生效,自然返回结果不符合预期。另外第二版里第二个索引名写错了,和最初查询声明的asso-456-*不一致,也会导致匹配失败。
正确写法
核心逻辑是给每个索引的匹配规则单独套一层bool.must,把「索引范围匹配」和「该索引下的字段匹配」做绑定,确保每个字段查询只在对应索引上执行,参考代码如下:
[ "index" => "items-123-*,asso-456-*", "body" => [ "query" => [ "bool" => [ "minimum_should_match" => 1, "should" => [ // 匹配items索引下title字段的结果 [ "bool" => [ "must" => [ ["term" => ["_index" => "items-123-*"]], ["match" => ["title" => "Civics"]] ] ] ], // 匹配asso索引下type字段的结果 [ "bool" => [ "must" => [ ["term" => ["_index" => "asso-456-*"]], ["match" => ["type" => "matchOf"]] ] ] ] ] ] ] ] ]
注意事项
- 如果需要精确匹配短语,把示例里的
match替换为match_phrase即可,整体逻辑不需要调整 - 建议始终显式声明
minimum_should_match => 1,避免bool查询存在其他must/filter子句时,should分支默认不做强制匹配的逻辑问题 _index字段支持通配符匹配,不需要写死完整的索引全名- 跨索引查询时要注意核对不同索引的字段名、字段类型,避免出现字段不存在、类型不匹配导致的查询失效问题
内容的提问来源于stack exchange,提问作者Bhumi Shah
相关产品推荐
相关产品推荐

