skip to Main Content
so here is my stories model, 


const storySchema = new mongoose.Schema(
  {
    avatar: { type: String, default: null },
    handle: { type: String, default: null },
    new: { type: Boolean, default: true },
    isLive: {type: Boolean, default: false},
    url: { type: String },
    type: { type: String },
    userName: { type: String, default: null },
    userId: { type: mongoose.Schema.Types.ObjectId, ref: "user_details" },
    isDeleted: { type: Boolean, default: false}
  },
  {
    timestamps: true,
    minimize: false
  }
)

userId is refered to user_details, so currently when i list stories they get listed like this ,

one story at a time and sorted by userId and createdAt,
As you can see the first 2 stories has the same userId, and what i want to do is that i group the stories by the user Object.

    
            "status": true,
            "data": [
                {
                    "_id": "633564ab793cf2a65f7c5dad",
                    "avatar": null,
                    "handle": null,
                    "new": true,
                    "isLive": false,
                    "url": "https://ellingsen-group.s3.amazonaws.com/media-1664443562856.png",
                    "type": "",
                    "userName": null,
                    "userId": "62eb5d58512ef25f1352830b",
                    "isDeleted": false,
                    "createdAt": "2022-09-29T09:26:03.846Z",
                    "updatedAt": "2022-09-29T09:26:03.846Z",
                    "__v": 0
                },
                {
                    "_id": "633564a9793cf2a65f7c5daa",
                    "avatar": null,
                    "handle": null,
                    "new": true,
                    "isLive": false,
                    "url": "https://ellingsen-group.s3.amazonaws.com/media-1664443559395.png",
                    "type": "",
                    "userName": null,
                    "userId": "62eb5d58512ef25f1352830b",
                    "isDeleted": false,
                    "createdAt": "2022-09-29T09:26:01.032Z",
                    "updatedAt": "2022-09-29T09:26:01.032Z",
                    "__v": 0
                },
                {
                    "_id": "633564e6793cf2a65f7c5dba",
                    "avatar": null,
                    "handle": null,
                    "new": true,
                    "isLive": false,
                    "url": "https://ellingsen-group.s3.amazonaws.com/media-1664443621607.png",
                    "type": "",
                    "userName": null,
                    "userId": "6290a0e7f03b0b3585e0f740",
                    "isDeleted": false,
                    "createdAt": "2022-09-29T09:27:02.608Z",
                    "updatedAt": "2022-09-29T09:27:02.608Z",
                    "__v": 0
                },
                {
                    "_id": "633564bf793cf2a65f7c5db0",
                    "avatar": null,
                    "handle": null,
                    "new": true,
                    "isLive": false,
                    "url": "https://ellingsen-group.s3.amazonaws.com/media-1664443582519.png",
                    "type": "",
                    "userName": null,
                    "userId": "6290a0e7f03b0b3585e0f740",
                    "isDeleted": false,
                    "createdAt": "2022-09-29T09:26:23.519Z",
                    "updatedAt": "2022-09-29T09:26:23.519Z",
                    "__v": 0
                }
            ],
            "totalPages": 1,
            "message": "Get user story Feed Success"
            
    
    

want to change this, so for user 1 ( story 1, 2, 3) user 2 ( story 1,2 ) etc,

here is the query for the result above.

const stories: any = await Story.StoryModel.aggregate([{ $match: { '_id': { $in: combined } } }, { $sort: { userId: -1, createdAt: -1 } }, listStoriesFacetPagination]).exec()

I tried grouping them like this (below) but i get at error saying that stories.groupBy is not a function, I’m stuck at this point and been trying to work this out for the past week.

 const groupByUserId = stories.groupBy((userId: any) => {
      return story.userId;
    }); 

and it would not work.

2

Answers


  1. Chosen as BEST ANSWER

    Here is the solution i found,

    const stories: any = await Story.StoryModel.aggregate([
          { $match: { '_id': { $in: combined } } }, 
          { $group: {
            _id: '$userId',
            stories: { $push: { url: '$url', _id: '$_id' , isLive: '$isLive', avatar: '$avatar', type:'$type', handle:'$handle', new:'$new', userName:'$userName', userId:'$userId', isDeleted:'$isDeleted', createdAt:'$createdAt'  } } } },
          { $sort: { createdAt: 1 } },
          listStoriesFacetPagination]).exec()
    

  2. You can achieve this by using reduce method, the code will be like this:

    const list = [{
        'name': 'John',
        'userId': '1',
      },
      {
        'name': 'Anne',
        'userId': '2',
      },
      {
        'name': 'John',
        'userId': '1',
      },
      {
        'name': 'Anne',
        'userId': '2',
      },
    ];
    
    const groups = list.reduce((groups, item) => ({
      ...groups,
      [item.userId]: [...(groups[item.userId] || []), item]
    }), {});
    

    This code will result in a object like this:

    {
     "1": [
        {'name': 'John', 'userId': '1'},
        {'name': 'John', 'userId': '1'}
       ],
     "2": [
        {'name': 'Anne', 'userId': '2'},
        {'name': 'Anne', 'userId': '2'}
       ]
    }
    

    Hope it help you 😀

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search