Skip to content

Instantly share code, notes, and snippets.

@kheengz
Last active January 28, 2021 08:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kheengz/22ffe8c87cf81583a4e6e6bf6e5f32ba to your computer and use it in GitHub Desktop.
Save kheengz/22ffe8c87cf81583a4e6e6bf6e5f32ba to your computer and use it in GitHub Desktop.
Query Posts by user -> paginated results and a total count.
// Aggregation using MongoDB
/**
* Query posts by user -> paginated results and a total count.
* @param userId {ObjectId} ID of user to retrieve posts for
* @param skip {Number} First row to return in results
* @param limit {Number} Last row to return in results
* @param sort {Object} sort query object
* @returns {Object} Object -> `{ rows, count }`
*/
function queryPostsByUser (userId, skip, limit, sort) {
// aggregation query
const query = [
// more lookups go here if you need them
// we have a many-to-one from Post -> user
{ $lookup: {
from: 'users',
localField: 'user',
foreignField: '_id',
as: 'user'
} },
// each post has a single user (author) so flatten it using $unwind
{ $unwind: '$user' },
// filter the results by our userId
{ $match: { 'user._id': userId } }
]
query.push(
{ $facet: {
metadata: [
{ $group: {
_id: null,
total: { $sum: 1 }
}},
],
data: [
{ $sort: sort },
{ $skip: skip },
{ $limit: limit },
]
}
{ $project: {
data: 1,
// Get total from the first element of the metadata array
total: { $arrayElemAt: [ '$metadata.total', 0 ] }
}
}
)
// { total: 10000, data: [ { x }, { y }, ... ] } // output
return Post
.aggregate(query)
.then(([{ total, data }]) => ({ count, rows }))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment