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

如何在同结构Elasticsearch索引demo-cm与demo-v2中识别缺失文档ID

问题描述

我有两个文档结构相同的Elasticsearch索引:demo-v2和demo-cm。

  • demo-v2的文档数据:
[{
    "_index": "demo-v2",
    "_type": "v2",
    "_id": "1",
    "_source": {
            "user": "kimchy",
        "message": "trying out Elastic Search"
    }
},{
    "_index": "demo-v2",
    "_type": "v2",
    "_id": "2",
    "_source": {
        "user": "kimchy",
        "message": "trying out Elastic Search"
    }
},{
    "_index": "demo-v2",
    "_type": "v2",
    "_id": "3",
    "_source": {
        "user": "kimchy",
        "message": "trying out Elastic Search"
    }
}]
  • demo-cm的文档数据:
[{
    "_index": "demo-cm",
    "_type": "cm",
    "_id": "1",
    "_source": {
        "user": "kimchy",
        "message": "trying out Elastic Search"
    }
}]

我需要找出demo-v2中存在但demo-cm中缺失的文档ID列表,期望结果是:

ids = ["2", "3"]

我尝试用Painless脚本编写了如下聚合查询,但没能得到准确结果,希望得到解决方案或示例:

{
  "size": 0,
  "aggs": {
    "missing_ids": {
      "scripted_metric": {
        "init_script": "state.docs = []",
        "map_script": "state.docs.add(doc._id.value)",
        "combine_script": "return state.docs",
        "reduce_script": "def unique_ids = []; def uniques = []; for (docs in states) {  unique_ids.addAll(docs); }  return unique_ids;"
      }
    }
  },
  "query": {
    "bool": {
      "must": [
        {
          "match_all": {}
        }
      ]
    }
  }
}

解决方案1:分步查询(简单易实现)

步骤1:获取demo-cm的所有文档ID

先查询demo-cm索引,用terms聚合提取所有ID:

{
  "size": 0,
  "aggs": {
    "cm_ids": {
      "terms": {
        "field": "_id",
        "size": 10000  // 根据实际数据量调整最大值
      }
    }
  }
}

执行后会得到demo-cm的所有ID列表(比如示例中的["1"])。

步骤2:筛选demo-v2中缺失的ID

把步骤1得到的ID放入bool查询的must_not条件,再聚合提取结果:

{
  "size": 0,
  "aggs": {
    "missing_ids": {
      "terms": {
        "field": "_id",
        "size": 10000
      }
    }
  },
  "query": {
    "bool": {
      "must_not": [
        {
          "terms": {
            "_id": ["1"]  // 替换为步骤1得到的ID列表
          }
        }
      ]
    }
  }
}

missing_ids聚合的buckets字段就是最终缺失的ID列表。


解决方案2:单查询脚本化聚合(一次性完成)

通过scripted_metric聚合同时查询两个索引,在脚本中完成ID对比:

{
  "size": 0,
  "indices": ["demo-v2", "demo-cm"],
  "aggs": {
    "missing_ids": {
      "scripted_metric": {
        "init_script": "state.v2_ids = new HashSet(); state.cm_ids = new HashSet();",
        "map_script": """
          if (doc['_index'].value == 'demo-v2') {
            state.v2_ids.add(doc['_id'].value);
          } else if (doc['_index'].value == 'demo-cm') {
            state.cm_ids.add(doc['_id'].value);
          }
        """,
        "combine_script": """
          def missing = new ArrayList();
          for (id in state.v2_ids) {
            if (!state.cm_ids.contains(id)) {
              missing.add(id);
            }
          }
          return missing;
        """,
        "reduce_script": """
          def all_missing = new HashSet();
          for (result in states) {
            all_missing.addAll(result);
          }
          return new ArrayList(all_missing);
        """
      }
    }
  }
}

脚本逻辑说明

  • init_script:初始化两个HashSet,分别存储两个索引的ID
  • map_script:根据文档所属索引,将ID添加到对应集合
  • combine_script:在分片层面对比集合,筛选出demo-v2独有的ID
  • reduce_script:合并所有分片的结果,返回最终缺失ID列表

原查询失效原因

你的脚本仅收集了所有查询到的ID,没有区分索引来源,也未做对比逻辑,最终返回的是两个索引的ID合集,无法得到缺失的ID。调整后的脚本增加了索引判断和集合对比逻辑,才能输出正确结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 02:39:58