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

如何在MongoDB中基于多条件数组实现批量文档匹配查询?

问题

我想知道能不能用$match/$elemMatch匹配符合输入对象条件数组的文档(0个或多个都可以),同时不用逐个查询每个条件项。我觉得$or没法直接用,因为查询条件数量不固定,难道只能动态构建$or查询?

示例数据

db.tshirts.insertMany([
    {_id:0, code: "123", label: "Yellow T-Shirt", style: [{ size: "SM", fabric: "cotton"},{ size: "MD", fabric: "bamboo"}]},
    {_id:1, code: "456", label: "Blue T-Shirt", style: [{ size: "MD", fabric: "bamboo"},{ size: "LG", fabric: "cotton"}]},
    {_id:2, code: "789", label: "Red T-Shirt", style: [{ size: "SM", fabric: "cotton"},{ size: "LG", fabric: "cotton"}]},
    {_id:3, code: "321", label: "Green T-Shirt", style: [{ size: "LG", fabric: "bamboo"},{ size: "LG", fabric: "bamboo"}]}
])

// 查询条件数组
var lookup = [
    {
        code: "123",
        style: {
            size: "SM"
        }
    },
    {
        code: "789",
        style: {
            size: "MD"
        }
    },
    {
        code: "321",
        style: {
            size: "LG"
        }
    },
]

期望输出

[
    {_id:0, code: "123", label: "Yellow T-Shirt", style: [{ size: "SM", fabric: "cotton"},{ size: "MD", fabric: "bamboo"}]},
    {_id:3, code: "321", label: "Green T-Shirt", style: [{ size: "LG", fabric: "bamboo"},{ size: "LG", fabric: "bamboo"}]}
]

解决方案

方案1:动态构建$or查询

其实动态构建$or是最直接且高效的方案,完全可行。你只需要遍历lookup数组,把每个条件项转换成对应的查询规则,再塞进$or数组里就行:

// 生成查询条件
const query = {
  $or: lookup.map(item => ({
    code: item.code,
    style: { $elemMatch: item.style }
  }))
};

// 执行查询
db.tshirts.find(query);

这个查询会匹配所有满足「code等于某个lookup项的code,且style数组里至少有一个元素符合对应size条件」的文档,正好能得到你想要的结果。

方案2:聚合管道实现(无需动态构建$or)

如果不想用$or,也可以用聚合管道结合$expr和$anyElementTrue来处理:

db.tshirts.aggregate([
  {
    $match: {
      $expr: {
        $anyElementTrue: {
          $map: {
            input: lookup,
            as: 'item',
            in: {
              $and: [
                { $eq: ['$code', '$$item.code'] },
                { $anyElementTrue: {
                    $map: {
                      input: '$style',
                      as: 's',
                      in: { $eq: ['$$s.size', '$$item.style.size'] }
                    }
                  }
                }
              ]
            }
          }
        }
      }
    }
  }
]);

逻辑是:遍历lookup数组,对每个文档检查是否存在某个lookup项满足「code相等,且style数组里有元素匹配对应size」,只要有一个符合就会被筛选出来。


补充说明

  • 动态$or方案性能更优,MongoDB可以利用code和style.size的索引(如果创建了的话)加速查询。
  • 聚合方案不用动态构建查询,但性能相对差一些,尤其是集合或lookup数组较大时,因为需要逐个文档做计算。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 02:43:19