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

如何在不使用$unwind的情况下执行多级$lookup查询?

不用$unwind实现多级$lookup的方案

完全可以做到!MongoDB 3.6及以上版本支持在$lookup阶段中使用自定义pipeline,这让我们能直接匹配数组中的ObjectId,无需先通过$unwind拆分数组。针对你的集合结构,具体的聚合查询如下:

db.venue.aggregate([
  {
    $lookup: {
      from: "reviews",
      let: { venueReviewIds: "$reviews" },
      pipeline: [
        {
          $match: {
            $expr: {
              $in: ["$_id", "$$venueReviewIds"]
            }
          }
        }
        // 这里还可以添加其他针对reviews的处理阶段,比如$project筛选字段、$sort排序等
      ],
      as: "reviewDetails"
    }
  }
])

代码解释:

  • let: 定义一个变量venueReviewIds,值就是当前venue文档中的reviews数组(存储的是review的ObjectId)
  • pipeline: 在这个子管道里,我们用$match结合$expr和$in操作符,找出所有_id存在于venueReviewIds数组中的reviews文档
  • as: 把匹配到的reviews结果数组命名为reviewDetails,最终会添加到每个venue文档中

查询结果示例:

执行后你会得到类似这样的文档结构,reviewDetails里直接包含了对应venue的所有reviews完整文档:

{
  "_id" : ObjectId("5acdb8f65ea63a27c1facf86"),
  "name" : "ASA College - Manhattan Campus",
  "addedBy" : ObjectId("5ac8ba3582c2345af70d4658"),
  "reviews" : [ ObjectId("5acdb8f65ea63a27c1facf8b"), ObjectId("5ad8288ccdd9241781dce698") ],
  "reviewDetails" : [
    { "_id" : ObjectId("5acdb8f65ea63a27c1facf8b"), "createdAt" : ISODate("...") },
    { "_id" : ObjectId("5ad8288ccdd9241781dce698"), "createdAt" : ISODate("...") }
  ]
}

这种方式不仅避免了$unwind带来的性能开销(尤其是当数组元素很多时),还能保持原始文档的结构完整性,非常适合你的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:35:01