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

如何在Elasticsearch中聚合指定用户的关联角色并筛选对应Workshop?

Elasticsearch嵌套聚合与筛选问题

数据映射

"properties": {
  "day": {
    "type": "date",
    "format": "yyyy-MM-dd"
  },
  "persons": {
    "type": "nested",
    "properties": {
      "id": {
        "type": "integer"
      },
      "name": {
        "type": "text",
        "analyzer": "final",
        "fields": {
          "raw": {
            "type": "keyword",
            "index": true
          }
        }
      },
      "role": {
        "type": "keyword"
      }
    }
  }
}

存储的数据

{
  "workshops": [
    {
      "day": "2023-12-01",
      "persons": [
        {
          "name": "Max",
          "role": "infrastructure"
        },
        {
          "name": "Sam",
          "role": "infrastructure"
        },
        {
          "name": "Sam",
          "role": "database"
        },
        {
          "name": "Peter",
          "role": "network"
        },
        {
          "name": "Peter",
          "role": "infrastructure"
        }
      ]
    },
    {
      "day": "2023-12-02",
      "persons": [
        {
          "name": "George",
          "role": "infrastructure"
        },
        {
          "name": "Michael",
          "role": "database"
        },
        {
          "name": "Michael",
          "role": "network"
        },
        {
          "name": "Sam",
          "role": "administration"
        }
      ]
    }
  ]
}

原聚合语句

{
  "aggregations": [
    {
      "persons": {
        "nested": {
          "path": "persons"
        },
        "aggs": {
          "nestedData": {
            "terms": {
              "field": "persons.name.raw"
            },
            "aggs": {
              "name": {
                "terms": {
                  "field": "persons.name.raw"
                }
              }
            }
          }
        }
      }
    },
    {
      "persons_role_de_de": {
        "nested": {
          "path": "persons"
        },
        "aggs": {
          "nestedData": {
            "terms": {
              "field": "persons.role"
            },
            "aggs": {
              "name": {
                "terms": {
                  "field": "persons.role"
                }
              }
            }
          }
        }
      }
    }
  ]
}

当前查询语句(筛选含Sam的文档)

{
  "query": {
    "bool": {
      "must": [
        {
          "nested": {
            "path": "persons",
            "query": {
              "bool": {
                "must": [
                  {
                    "match": {
                      "persons.name": "sam"
                    }
                  }
                ]
              }
            }
          }
        }
      ]
    }
  }
}

问题现象

执行match_all查询时聚合结果符合预期,但用上述查询筛选含Sam的文档后,角色聚合统计的是文档内所有人员的角色,而非仅Sam的角色(预期结果:infrastructure(1)、database(1)、administration(1))。最终目标是找到Sam担任database角色的workshop,但当前聚合和查询配置无法实现。


解决方案

1. 仅统计Sam的角色

嵌套查询仅筛选出包含Sam的文档,但聚合会遍历文档内所有persons嵌套对象。需在聚合的嵌套层级内添加过滤器,仅针对Sam的记录做统计:

{
  "query": {
    "bool": {
      "must": [
        {
          "nested": {
            "path": "persons",
            "query": {
              "match": {
                "persons.name": "sam"
              }
            }
          }
        }
      ]
    }
  },
  "aggs": {
    "persons": {
      "nested": {
        "path": "persons"
      },
      "aggs": {
        "only_sam": {
          "filter": {
            "match": {
              "persons.name": "sam"
            }
          },
          "aggs": {
            "sam_roles": {
              "terms": {
                "field": "persons.role"
              }
            }
          }
        }
      }
    }
  }
}

此语句会在聚合中先过滤出Sam的记录,再统计其角色分布,得到预期结果。

2. 找到Sam担任database角色的workshop

直接使用嵌套查询同时匹配name=Sam和role=database,即可定位目标workshop:

{
  "query": {
    "nested": {
      "path": "persons",
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "persons.name": "sam"
              }
            },
            {
              "match": {
                "persons.role": "database"
              }
            }
          ]
        }
      },
      "inner_hits": {
        "size": 10
      }
    }
  }
}

查询结果会返回包含Sam且角色为database的workshop文档,inner_hits字段会显示匹配的具体persons对象。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 01:36:03