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

如何在Mongoose中按关联用户详情对故事列表进行分组?

How to Group Stories by User (userId) in 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:

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:

  1. stories is the full query result object (with status, data, etc.), not the array of stories. You should be targeting stories.data instead.
  2. Native JavaScript arrays don't have a built-in groupBy method—this is a Lodash utility, so you need to import Lodash to use it.

内容的提问来源于stack exchange,提问作者the eg dev

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 16:17:45