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

Elasticsearch 7.17中实现SQL IN子查询等价操作获取指定部门员工最新项目

问题描述

我的Elasticsearch文档层级结构如下:

{
  "Department": [
    {
      "Employee": [
        {
          "Projects": []
        }
      ]
    }
  ]
}

文档以项目为存储粒度,需要实现类似SQL的IN查询效果:传入指定部门后,获取该部门下每位员工正在参与的最新项目列表。对应的SQL语句如下:

Select top 1 from Project where employee_id in (select employee_id from department where department_code='Dept')

使用的Elasticsearch版本为7.17。

解决方案

1. 确认Mapping配置

由于文档包含多层嵌套数组,必须将Department和Employee字段设置为nested类型,否则Elasticsearch会自动扁平化数组结构,导致部门、员工、项目的关联关系丢失。示例Mapping如下:

PUT /projects_index
{
  "mappings": {
    "properties": {
      "Department": {
        "type": "nested",
        "properties": {
          "Employee": {
            "type": "nested",
            "properties": {
              "employee_id": {"type": "keyword"},
              "Projects": {
                "type": "nested",
                "properties": {
                  "project_id": {"type": "keyword"},
                  "project_name": {"type": "text"},
                  "create_time": {"type": "date"}
                }
              }
            }
          },
          "department_code": {"type": "keyword"}
        }
      }
    }
  }
}

2. 实现查询DSL

通过bool查询结合nested查询定位指定部门,再通过聚合获取每位员工的最新项目:

GET /projects_index/_search
{
  "size": 0,
  "query": {
    "nested": {
      "path": "Department",
      "query": {
        "bool": {
          "must": [
            {"term": {"Department.department_code": "Dept"}}
          ]
        },
        "inner_hits": {
          "path": "Department.Employee"
        }
      }
    }
  },
  "aggs": {
    "group_by_employee": {
      "nested": {
        "path": "Department.Employee"
      },
      "aggs": {
        "filter_employees": {
          "filter": {
            "nested": {
              "path": "Department",
              "query": {
                "term": {"Department.department_code": "Dept"}
              }
            }
          },
          "aggs": {
            "latest_project": {
              "top_hits": {
                "size": 1,
                "sort": [{"Department.Employee.Projects.create_time": {"order": "desc"}}],
                "_source": {
                  "includes": ["Department.Employee.employee_id", "Department.Employee.Projects.*"]
                }
              }
            }
          }
        }
      }
    }
  }
}

3. 查询逻辑说明

  • nested查询:精准匹配目标department_code的部门,确保只处理该部门下的关联数据。
  • group_by_employee聚合:按员工维度分组,保证每个员工的结果独立返回。
  • top_hits聚合:通过create_time倒序排序,只取每个员工的最新一条项目数据,size:1控制返回数量。

如果你的文档结构是单个项目作为独立文档(即每个文档对应一个项目,直接包含所属员工ID和部门编码),可以简化为以下查询:

GET /projects_index/_search
{
  "size": 0,
  "aggs": {
    "filter_target_dept": {
      "filter": {"term": {"department_code": "Dept"}},
      "aggs": {
        "group_by_employee": {
          "terms": {"field": "employee_id", "size": 100},
          "aggs": {
            "latest_project": {
              "top_hits": {
                "size": 1,
                "sort": [{"create_time": {"order": "desc"}}]
              }
            }
          }
        }
      }
    }
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 23:53:35