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

MongoDB多文档数据获取问题:使用Aggregate需返回多条记录

How to Return Multiple Records with MongoDB Aggregate for Your Book Schema

Hey Dave, let's tackle this problem you're having with MongoDB's aggregate pipeline. It sounds like you're using aggregate() but ending up with a single aggregated result instead of the multiple individual records you need—let's fix that.

First, let's recap your Book Schema to make sure we're on the same page:

var BookSchema = new Schema({ 
  BookName: { type: String, required: true, index: { unique: true }}, 
  userAssignedId: { type: Schema.Types.ObjectId}, 
  BookAuthorId: { type: Schema.Types.ObjectId, required: true}, 
  BookVersionId :{ type: Schema.Types.ObjectId, required: true} 
});

Key Issue to Fix: Avoid Unnecessary $group Stages

If your current aggregate pipeline uses $group with _id: null, that's why you're getting a single merged result—this syntax aggregates all documents into one. To keep multiple records, either:

  • Remove the $group stage entirely (to retain individual book documents, possibly with joined data), or
  • Use $group with a specific field (like BookAuthorId) to group related records while keeping groups separate.

Example 1: Return Individual Book Records with Joined Data

If you want to fetch each book as a separate record, plus join related data (like author, version, assigned user), use $lookup to join collections and $unwind to flatten the joined arrays (without merging records):

Book.aggregate([
  // Join with authors collection (replace "authors" with your actual collection name)
  {
    $lookup: {
      from: "authors",
      localField: "BookAuthorId",
      foreignField: "_id",
      as: "bookAuthor"
    }
  },
  // Join with versions collection
  {
    $lookup: {
      from: "versions",
      localField: "BookVersionId",
      foreignField: "_id",
      as: "bookVersion"
    }
  },
  // Join with users collection (for assigned user, optional)
  {
    $lookup: {
      from: "users",
      localField: "userAssignedId",
      foreignField: "_id",
      as: "assignedUser"
    }
  },
  // Flatten joined arrays to single objects (keep null/empty records if no match)
  {
    $unwind: {
      path: "$bookAuthor",
      preserveNullAndEmptyArrays: true
    }
  },
  {
    $unwind: {
      path: "$bookVersion",
      preserveNullAndEmptyArrays: true
    }
  },
  {
    $unwind: {
      path: "$assignedUser",
      preserveNullAndEmptyArrays: true
    }
  },
  // Optional: Shape the output to only include fields you need
  {
    $project: {
      _id: 1,
      BookName: 1,
      Author: "$bookAuthor.AuthorName", // Adjust to your Author schema's field
      Version: "$bookVersion.VersionNumber", // Adjust to your Version schema's field
      AssignedUser: "$assignedUser.Username" // Adjust to your User schema's field
    }
  }
])
.exec((err, results) => {
  if (err) console.error(err);
  console.log(results); // This will return an array of individual book records!
});

Example 2: Group Records but Keep Multiple Entries per Group

If you want to group books (e.g., by author) but still see all books in each group, use $group with $push to collect related records into an array:

Book.aggregate([
  { $lookup: { /* Same author join as above */ } },
  { $unwind: "$bookAuthor" },
  // Group books by author, keeping all books in each group
  {
    $group: {
      _id: "$BookAuthorId",
      AuthorName: { $first: "$bookAuthor.AuthorName" },
      BooksByAuthor: { 
        $push: { 
          BookName: "$BookName", 
          Version: "$bookVersion.VersionNumber" 
        } 
      }
    }
  }
])

This will return one record per author, each containing an array of their books.


Quick Tip for Historical Data

You mentioned a historical data schema—if you need to join that too, just add another $lookup stage pointing to your historical collection (e.g., bookHistories) and link it via the book's _id:

{
  $lookup: {
    from: "bookHistories",
    localField: "_id",
    foreignField: "BookId", // Assuming your history records have a BookId field
    as: "History"
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 03:44:30