如何在Mongoose中按关联用户详情对故事列表进行分组?
Looks like your issue comes from either stories not being a plain JavaScript array, or not having Lodash's groupBy method available. Plus, grouping directly at the database level is way more efficient than handling it in code. Here are two solid solutions for you:
Option 1: Group Directly in MongoDB Aggregation Pipeline (Recommended)
You can modify your existing aggregation pipeline to add a $group stage, which will group stories by userId right in the database. If you need to pull in user details from the user_details collection, you can also add a $lookup stage:
const stories = await Story.StoryModel.aggregate([ // Keep your original match condition { $match: { '_id': { $in: combined } } }, // Optional: Join with user_details to get full user info { $lookup: { from: "user_details", // Name of the user collection localField: "userId", foreignField: "_id", as: "user" } }, // Optional: Flatten the user array if you don't want nested data { $unwind: "$user" }, // Group stories by userId { $group: { _id: "$userId", userDetails: { $first: "$user" }, // Grab user info once per group stories: { $push: "$$ROOT" }, // Collect all stories for this user // Alternatively, pull specific user fields directly if you don't need full details: // userName: { $first: "$userName" }, // avatar: { $first: "$avatar" } } }, // Optional: Sort groups by the latest story time { $sort: { "stories.createdAt": -1 } }, // Keep your existing pagination facet listStoriesFacetPagination ]).exec();
This will return results already grouped by user, with each group containing user details and their associated stories—no extra code processing needed.
Option 2: Group in JavaScript (If You Can't Modify the Aggregation)
If you need to stick with your current query, you can process the returned data array directly in your code:
Method 1: Native JavaScript Grouping
// Assume your query result is stored in 'result' const groupedStories = result.data.reduce((acc, story) => { // Convert ObjectId to string to avoid key issues const userId = story.userId.toString(); if (!acc[userId]) { acc[userId] = { userId: story.userId, userName: story.userName, avatar: story.avatar, stories: [] }; } acc[userId].stories.push(story); return acc; }, {}); // Convert to array format if needed const groupedArray = Object.values(groupedStories);
Method 2: Use Lodash's groupBy (Requires Lodash Installation)
First install Lodash:
npm install lodash
Then use it in your code:
const _ = require('lodash'); // Group the data array by userId const groupedByUserId = _.groupBy(result.data, 'userId'); // Convert to array format if needed const groupedArray = Object.values(groupedByUserId);
Why Your Original Code Failed
Your stories.groupBy(...) call threw an error for two reasons:
storiesis the full query result object (withstatus,data, etc.), not the array of stories. You should be targetingstories.datainstead.- Native JavaScript arrays don't have a built-in
groupBymethod—this is a Lodash utility, so you need to import Lodash to use it.
内容的提问来源于stack exchange,提问作者the eg dev

