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

使用MongoDB聚合$filter统计两个数组匹配元素数量的问题

MongoDB聚合统计数组元素匹配数量问题解决

问题说明

需要统计用户输入数组与后端存储的数组之间的匹配元素个数:

  • 用户输入[1,2,3,4],与后端数组[1,2,3,4]比对,期望返回匹配数4
  • 用户输入[1,2,3,5],与后端数组[1,2,3,4]比对,期望返回匹配数3
    但现有聚合查询返回结果错误,完全匹配时仅返回1,无法实现需求。

现有查询的问题

原查询使用$filter遍历entries数组,判断整个numbers数组是否与输入数组完全相等,最终统计的是匹配的entries条目数,而非数组内元素的匹配数量。这就是为什么完全匹配时返回1——仅表示有一个entries元素的numbers数组和输入数组完全一致,而非4个元素匹配。

原查询代码:

db.collection.aggregate({
  $match: {
    "entries.numbers": {
      $in: [1,2,3,4]
    }
  }
},
{
  "$addFields": {
    "matchingCount": {
      $size: {
        $filter: {
          input: "$entries",
          as: "e",
          cond: {
            $eq: ["$$e.numbers", [1,2,3,4]]
          }
        }
      }
    }
  }
})

解决方案

使用$setIntersection获取两个数组的交集,再用$size获取交集的长度,即可得到元素级别的匹配数量。根据需求不同,有三种实现方式:

方式1:为每个entries元素计算匹配数

如果需要给每个entries对象添加对应的元素匹配数,用$map遍历entries数组,对每个元素的numbers数组计算交集大小:

db.collection.aggregate([
  {
    $match: {
      "entries.numbers": { $in: [1,2,3,4] }
    }
  },
  {
    $addFields: {
      entriesWithMatch: {
        $map: {
          input: "$entries",
          as: "e",
          in: {
            numbers: "$$e.numbers",
            matchingCount: {
              $size: {
                $setIntersection: ["$$e.numbers", [1,2,3,4]]
              }
            }
          }
        }
      }
    }
  }
])

方式2:计算所有entries元素的总匹配数

如果需要统计整个文档中所有entries的numbers数组与输入数组的总匹配元素数,用$reduce累加每个元素的匹配数:

db.collection.aggregate([
  {
    $match: {
      "entries.numbers": { $in: [1,2,3,4] }
    }
  },
  {
    $addFields: {
      totalMatchingCount: {
        $reduce: {
          input: "$entries",
          initialValue: 0,
          in: {
            $add: [
              "$$value",
              { $size: { $setIntersection: ["$$this.numbers", [1,2,3,4]] } }
            ]
          }
        }
      }
    }
  }
])

方式3:针对单个numbers数组计算匹配数

如果文档中entries仅包含一个numbers数组,可直接提取该数组计算交集:

db.collection.aggregate([
  {
    $match: {
      "entries.numbers": { $in: [1,2,3,4] }
    }
  },
  {
    $addFields: {
      matchingCount: {
        $size: {
          $setIntersection: ["$entries.0.numbers", [1,2,3,4]]
        }
      }
    }
  }
])

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 03:11:23