Elasticsearch多值字段匹配问题:如何匹配同一记录全部指定值
解决Elasticsearch中数组字段匹配所有指定值的问题
首先得明确:你用terms查询时,Elasticsearch默认是**逻辑或(OR)**关系——只要文档的routes数组里包含任一指定值,就会被匹配,这就是为什么你得到的是符合任一条件的结果,而非同时满足两个值的文档。
不需要把映射改成nested类型(除非你的数组是复杂对象结构,而这里只是简单的long数组),有两种更直接的方式实现“同时包含所有指定值”的需求:
方法1:用bool.must结合多个term查询
这是最直观的方式,让每个值的匹配都成为必须满足的条件:
GET /flight_routes/_search { "query": { "bool": { "filter": [ {"term": {"routes": 5463}}, {"term": {"routes": 3452}} ] } } }
filter中的多个条件是**逻辑与(AND)**关系,只有同时包含两个值的文档才会被返回。
方法2:使用terms_set查询(更灵活)
如果后续需要匹配的数组值数量不固定,terms_set是更合适的选择,它可以指定必须匹配的最小数量:
GET /flight_routes/_search { "query": { "terms_set": { "routes": { "terms": [5463, 3452], "minimum_should_match_script": { "source": "params.num_terms" } } } } }
这里minimum_should_match_script设置为params.num_terms,意味着必须匹配所有传入的terms,刚好满足你的需求。之后如果要调整匹配规则(比如至少匹配2个里的1个),修改脚本内容即可。
为什么不需要nested类型?
nested类型是用来处理对象数组的,比如你的routes如果是[{"id":5463}, {"id":3452}]这种结构,普通查询会把对象扁平化导致错误匹配。但你的场景是简单的long数组,Elasticsearch会自动将数组元素索引为独立词条,用上面两种方法就能实现精确的“与”匹配。
内容的提问来源于stack exchange,提问作者syv
相关产品推荐
相关产品推荐

