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.
CodePudding user response:
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 :D
CodePudding user response:
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()