You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

如何编写Elasticsearch过滤查询获取符合多text条件的产品

问题分析

你的核心问题在于索引是扁平的多文档对应单个产品结构,而你之前的bool must查询是要求单条文档同时满足所有条件——但单条文档的text字段只能是pcmac中的一个,不可能同时存在,所以自然查不到结果。你需要的是跨文档的匹配逻辑:同一个product_id下,存在两条key=A1的文档,分别包含text=pctext=mac

正确解决方案

下面提供两种可行的查询方式,根据你的需求选择:

方式1:先聚合筛选目标产品ID,再查询详情

这种方式先通过聚合找出符合条件的product_id,再用这些ID查询产品数据,逻辑清晰且性能较好:

{
  "size": 0, // 不需要返回原始文档,只看聚合结果
  "query": {
    "bool": {
      "must": [{"term": {"key": "A1"}}], // 先限定key=A1
      "should": [
        {"term": {"text": "pc"}},
        {"term": {"text": "mac"}}
      ],
      "minimum_should_match": 1 // 至少匹配其中一个text值
    }
  },
  "aggs": {
    "group_by_product": {
      "terms": {"field": "product_id"}, // 按产品ID分组
      "aggs": {
        "unique_texts": {
          "terms": {"field": "text"} // 统计每组内的text值
        },
        "has_both_pc_mac": {
          "bucket_selector": {
            "buckets_path": {"text_count": "unique_texts._bucket_count"},
            "script": "params.text_count == 2" // 筛选出同时包含2种text值的分组
          }
        }
      }
    }
  }
}

聚合结果里的group_by_product.buckets就是所有符合条件的产品ID,之后你可以用terms查询获取这些ID对应的完整数据。

方式2:直接返回符合条件的产品(需脚本支持)

如果想一步拿到产品数据,可以用collapseproduct_id折叠文档,再通过脚本验证是否同时包含两种text值:

{
  "query": {
    "bool": {
      "must": [{"term": {"key": "A1"}}],
      "should": [
        {"term": {"text": "pc"}},
        {"term": {"text": "mac"}}
      ],
      "minimum_should_match": 1
    }
  },
  "collapse": {
    "field": "product_id",
    "inner_hits": {
      "name": "matched_texts",
      "size": 10 // 取该产品下所有匹配的文档
    }
  },
  "post_filter": {
    "script": {
      "script": "params._source.matched_texts.hits.hits.stream().map(hit -> hit._source.text).distinct().size() == 2"
    }
  }
}

这个查询会直接返回同时包含pcmac的产品,注意需要确保你的Elasticsearch集群开启了脚本支持(默认可能关闭,需要修改配置)。

为什么之前的查询失败?

再回顾下你之前的错误逻辑:

  • 第一种查询的bool must要求单条文档同时满足key=A1text=pctext=mac,但你的每条文档text只有一个值,不可能同时匹配。
  • 第二种查询的filter里嵌套了两个bool must,本质还是要求单条文档同时满足key=A1+text=Mackey=A1+text=Pc,同样不符合你的多文档结构。

内容的提问来源于stack exchange,提问作者Martin-

火山引擎 最新活动