You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用ElasticSearch DSL统计GT与MX共享的typeA嵌套条目数

需求:统计GT和MX客户共享的typeA条目数量

现有文档数据

以下是Elasticsearch中的文档(已修正JSON语法错误):

Document 1

{
    "Id": 6000,
    "customerName": "GT", 
    "pages": [
        {
            "fieldType": "typeA",
            "fieldId": 1001
        },
        {
            "fieldType": "typeB",
            "fieldId": 1002
        }
    ]
}

Document 2

{
    "Id": 6001,
    "customerName": "MX", 
    "pages": [
        {
            "fieldType": "typeA",
            "fieldId": 1001
        }
    ]
}

Document 3

{
    "Id": 6002,
    "customerName": "MX", 
    "pages": [
        {
            "fieldType": "typeB",
            "fieldId": 1002
        },
        {
            "fieldType": "typeC",
            "fieldId": 1003
        }
    ]
}

Document 4

{
    "Id": 6003,
    "customerName": "GT", 
    "pages": [
        {
            "fieldType": "typeA",
            "fieldId": 1005
        },
        {
            "fieldType": "typeC",
            "fieldId": 1003
        }
    ]
}

Document 5

{
    "Id": 6004,
    "customerName": "MX", 
    "pages": [
        {
            "fieldType": "typeA",
            "fieldId": 1005
        }
    ]
}

需求说明

需要统计嵌套在pages字段中的typeA条目数量,但仅统计那些同时出现在customerName为GT和MX的文档中的条目——即找出两类客户文档共享的fieldId对应的typeA条目。示例中fieldId=1001和fieldId=1005符合条件,总计2个。

原尝试的DSL(无法满足需求)

以下查询仅能统计GT或MX的typeA条目,无法筛选出同时存在的共享条目:

{
  "query": { 
    "bool": {
      "must": [
        {
          "bool": {
            "should": [
              {
                "match": {
                  "customerName": "CN"
                }
              },
              {
                "match": {
                  "customerName": "MX"
                }
              }
            ]
          },
          {
            "nested": {
              "path": "pages",
              "query": {
                "term": {
                  "fieldType": "typeA"
                }
              }
            }
          }  
        }
      ]
    }
  }
}

正确的DSL查询方案

要实现需求,需要通过嵌套聚合+桶筛选来找出同时被两类客户包含的typeA条目,具体DSL如下:

{
  "size": 0,
  "query": {
    "bool": {
      "must": [
        {
          "nested": {
            "path": "pages",
            "query": {
              "term": {
                "pages.fieldType": "typeA"
              }
            }
          }
        },
        {
          "terms": {
            "customerName": ["GT", "MX"]
          }
        }
      ]
    }
  },
  "aggs": {
    "nested_pages_context": {
      "nested": {
        "path": "pages"
      },
      "aggs": {
        "filter_typeA_entries": {
          "filter": {
            "term": {
              "pages.fieldType": "typeA"
            }
          },
          "aggs": {
            "group_by_fieldId": {
              "terms": {
                "field": "pages.fieldId"
              },
              "aggs": {
                "count_distinct_customers": {
                  "terms": {
                    "field": "customerName"
                  }
                },
                "keep_only_shared_entries": {
                  "bucket_selector": {
                    "buckets_path": {
                      "customerCount": "count_distinct_customers._bucket_count"
                    },
                    "script": "params.customerCount == 2"
                  }
                }
              }
            }
          }
        }
      }
    },
    "total_shared_typeA_count": {
      "bucket_script": {
        "buckets_path": {
          "validBuckets": "nested_pages_context>filter_typeA_entries>group_by_fieldId._bucket_count"
        },
        "script": "params.validBuckets"
      }
    }
  }
}

关键逻辑说明

  1. 外层查询:先过滤出包含typeA嵌套条目,且客户为GT或MX的文档,缩小聚合范围。
  2. 嵌套聚合:进入pages嵌套字段的上下文,确保聚合操作针对嵌套条目。
  3. 筛选typeA:仅保留fieldType=typeA的嵌套条目。
  4. 按fieldId分组:将相同fieldId的条目归为一组。
  5. 客户去重计数:统计每个fieldId对应的不同客户数量。
  6. 桶筛选:只保留客户数量为2的分组(即同时被GT和MX包含的fieldId)。
  7. 最终统计:通过bucket_script计算符合条件的分组数量,即为共享的typeA条目总数。

注意事项

  • 确保pages.fieldId字段为keyword类型(或使用其对应的keyword子字段,如pages.fieldId.keyword),否则分词会导致分组错误。
  • 若使用Elasticsearch 7.x及以上版本,脚本默认使用Painless,无需额外配置。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 21:40:22