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

MongoDB如何用嵌套$lookup关联users、bookHistory、books三集合查询

解决方案

你需要实现嵌套关联查询,这里提供两种常用实现方式:

方式1:原生MongoDB聚合管道(推荐,适配你当前写的pipeline逻辑)

MongoDB 3.6及以上版本支持$lookup嵌套管道,可以直接在关联bookHistory的同时完成内层books集合的关联,调整后的pipeline如下:

const pipeline = [
  { $match: query },
  { $project: projection },
  {
    $lookup: {
      from: 'bookHistory',
      let: { userUid: '$uid' },
      pipeline: [
        // 匹配对应用户的借阅记录
        { $match: { $expr: { $eq: ['$uid', '$$userUid'] } } },
        // 内层关联books集合,填充bookDetails
        {
          $lookup: {
            from: 'books',
            localField: 'bookId',
            foreignField: '_id',
            as: 'bookDetails'
          }
        },
        // 因为单条借阅记录对应唯一一本书,将bookDetails数组转成对象
        { $unwind: '$bookDetails' },
        // 可选:如果不需要返回bookHistory的多余字段,可在这里加$project过滤
        {
          $project: {
            tookOn: 0,
            dueOn: 0,
            addedOn: 0
          }
        }
      ],
      as: 'bookHistory'
    }
  }
];

方式2:Mongoose 深populate(如果你用Mongoose ODM操作数据库)

如果你的项目用Mongoose,且已经在Schema中定义了关联关系,可以更简单的实现嵌套填充:

  1. 先确认Schema定义:
// BookHistory Schema
const bookHistorySchema = new mongoose.Schema({
  bookId: { type: String, ref: 'Books' },
  // 其他字段省略
})
// User Schema
const userSchema = new mongoose.Schema({
  uid: String,
  // 其他字段省略
})
  1. 查询语句:
const userList = await User.find(query)
  .select(projection)
  .populate({
    path: 'bookHistory',
    populate: {
      path: 'bookId',
      as: 'bookDetails'
    }
  })

两种方式返回的结构都和你要求的格式完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 08:36:02