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

MongoDB聚合:如何筛选数组不含根文档_id的文档?

问题原因分析

你的两种查询方式失效,核心原因是MongoDB对数组字段的匹配逻辑和你预期的不一致:

  1. $ne 条件的问题:

    • 普通$match查询中不能直接用$_id作为操作符的值,MongoDB会将"$_id"视为字符串字面量,而非文档自身的_id字段值。
    • 针对数组字段使用$ne时,只要数组中存在任意一个元素不满足匹配条件,整个文档就会被返回。你的示例文档中存在一个refId不等于根_id的元素,因此会被错误返回。
  2. $nin 条件的问题:
    $nin的逻辑是"数组中存在至少一个元素不在指定列表内",而非"数组中所有元素都不在列表内"。你的目标文档里有一个refId不在你指定的ObjectId数组中,所以符合$nin的匹配条件,导致文档被返回。

正确实现方案

要筛选出applications.firstTimeInstalled数组中完全不存在refId等于根文档_id的文档,需要使用聚合表达式$expr来引用文档自身字段,并结合数组检查逻辑:

方案一:使用 $in + $not

{
  $match: {
    $expr: {
      $not: {
        $in: ["$_id", "$applications.firstTimeInstalled.refId"]
      }
    }
  }
}

逻辑:$in检查根文档的_id是否存在于applications.firstTimeInstalled.refId数组中,$not取反后,就会筛选出不存在匹配项的文档。

方案二:使用 $filter + $size

{
  $match: {
    $expr: {
      $eq: [
        {
          $size: {
            $filter: {
              input: "$applications.firstTimeInstalled",
              cond: { $eq: ["$$this.refId", "$_id"] }
            }
          }
        },
        0
      ]
    }
  }
}

逻辑:用$filter过滤出数组中refId等于根_id的元素,再用$size获取过滤后的数组长度。当长度为0时,说明数组中没有匹配的refId,符合筛选要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 22:35:42