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

ElasticSearch:嵌套对象数组的高级搜索实现方案咨询

问题描述

假设Elasticsearch中存储了如下文档:

[
  {
    "id": "349dec5f-4ddf-4faa-beb0-79a0ea08bad6",
    "name": "Iphone 13",
    "criteria": [
      {
        "name": "color",
        "options": ["Midnight", "Blue", "Green"]
      }
    ]
  },
  {
    "id": "1a63de5a-4335-4e0d-83ab-c820d57709bd",
    "name": "IPhone 14",
    "criteria": [
      {
        "name": "color",
        "options": ["Midnight", "Purple", "Red"]
      },
      {
        "name": "size",
        "options": ["128GB", "256GB"]
      }
    ]
  },
  {
    "id": "eae5672f-2153-4f7d-be68-122e6d9fe5e1",
    "name": "Iphone 14 Pro",
    "criteria": [
      {
        "name": "color",
        "options": ["Black", "Blue", "Red"]
      },
      {
        "name": "size",
        "options": ["64GB", "128GB", "256GB"]
      }
    ]
  }
]

文档的类型映射如下:

{
  "properties": {
    "id": { "type": "keyword", "ignore_above": 36 },
    "name": { "type": "text" },
    "category": { "type": "keyword", "ignore_above": 36 },
    "criteria": {
      "type": "nested",
      "properties": {
        "name": { "type": "keyword", "ignore_above": 500 },
        "options": { "type": "keyword", "ignore_above": 500 }
      }
    }
  }
}

其中criteria为嵌套对象数组,包含criteria.name和criteria.options字段,可存储color、size之外的其他值。

现在需要根据HTTP请求中的filter对象筛选文档,示例请求中的filter参数如下:

{
  "search": null,
  "filter": {
    "criteria": [
      {
        "name": "color",
        "options": ["Blue", "Red"],
        "operator": "OR"
      },
      {
        "name": "size",
        "options": ["64GB", "128GB"],
        "operator": "OR"
      }
    ]
  }
}

筛选逻辑为:

文档需同时满足:

  1. 存在criteria.name为color的嵌套对象,且其options包含Blue或Red
  2. 存在criteria.name为size的嵌套对象,且其options包含64GB或128GB

按此条件应返回IPhone 14和Iphone 14 Pro两个文档,如何在Elasticsearch中实现该需求?

解决方案

由于criteria是nested类型,普通查询无法正确关联嵌套对象内的字段,必须使用nested查询确保每个条件作用于同一个嵌套对象实例。我们可以通过外层bool.must组合多个nested查询,实现“同时满足多个筛选维度”的逻辑,每个nested查询对应一个筛选条件(color或size)。

对应的Elasticsearch查询DSL如下:

{
  "query": {
    "bool": {
      "must": [
        // 处理color筛选条件
        {
          "nested": {
            "path": "criteria",
            "query": {
              "bool": {
                "must": [
                  { "term": { "criteria.name": "color" } },
                  { "terms": { "criteria.options": ["Blue", "Red"] } }
                ]
              }
            }
          }
        },
        // 处理size筛选条件
        {
          "nested": {
            "path": "criteria",
            "query": {
              "bool": {
                "must": [
                  { "term": { "criteria.name": "size" } },
                  { "terms": { "criteria.options": ["64GB", "128GB"] } }
                ]
              }
            }
          }
        }
      ]
    }
  }
}

逻辑说明:

  • 外层bool.must:确保两个nested查询的条件同时满足,对应需求中的“color条件且size条件”。
  • 每个nested查询:指定path为criteria,确保查询只作用于单个嵌套对象。
    • term查询匹配criteria.name,锁定要筛选的维度(color或size)。
    • terms查询匹配criteria.options,该查询本身就是OR逻辑,正好对应“options包含任意指定值”的要求。

动态生成查询思路:

如果需要根据前端传入的filter参数动态生成DSL,只需遍历filter中的每个criteria项,为每个项生成对应的nested查询块,再将所有块放入外层bool.must数组即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 00:22:48