I have a database of users that have skills. I have set up a way to find users in the database using am aggregation method included in mongoose. Depending on the search criteria I input into the aggregation, the results may be too big to actually display on my front end app. I am curious how I can paginate an aggregation query with the typical limit, page, and skip variables like you would do in a typical GET request.
Here is my aggregation query:
const foundUsers = await User.aggregate([
{
$addFields: {
matchingSkills: {
$filter: {
input: '$skills',
cond: {
$or: test,
},
},
},
requiredSkills,
},
},
{
$addFields: {
// matchingSkills: '$$REMOVE',
percentageMatch: {
$multiply: [
{ $divide: [{ $size: '$matchingSkills' }, skillSearch.length] }, // yu already know how many values you need to pass, thats' why `2`
100,
],
},
},
},
{
$addFields: {
matchingSkillsNames: {
$map: {
input: '$matchingSkills',
as: 'matchingSkill',
in: '$$matchingSkill.skill',
},
},
},
},
{
$addFields: {
missingSkills: {
$filter: {
input: '$requiredSkills',
cond: {
$not: {
$in: ['$$this', '$matchingSkillsNames'],
},
},
},
},
},
},
{
$match: { percentageMatch: { $gte: 25 } },
},
]);
Passing these skills to this aggregate function:
{
"skillSearch": [
{
"class": "skills",
"skill": "SQL",
"operator": "GT",
"yearsExperience": 6
},
{
"class": "skills",
"skill": "C",
"operator": "GT",
"yearsExperience": 1
}
]
}
Will result in a response similar to this:
{
"_id": "60184ce81e65633873d709aa",
"name": "Brad",
"email": "[email protected]",
"password": "$2a$12$37v2RwaO5LhSMT8GJQSZyel.Aawn6AmlqqSOkZtopqIIXyJ0LRBfu",
"__v": 0,
"skills": [
{
"_id": "60a306ce819cde701c1934a8",
"skill": "SQL",
"yearsExperience": 8
},
{
"_id": "60a306ce819cde701c1934a9",
"skill": "C",
"yearsExperience": 5
},
{
"_id": "60a306ce819cde701c1934aa",
"skill": "PL/I",
"yearsExperience": 2
},
{
"_id": "60a306ce819cde701c1934ab",
"skill": "Awk",
"yearsExperience": 9
}
],
"matchingSkills": [
{
"_id": "60a306ce819cde701c1934a8",
"skill": "SQL",
"yearsExperience": 8
},
{
"_id": "60a306ce819cde701c1934a9",
"skill": "C",
"yearsExperience": 5
}
],
"requiredSkills": [
"SQL",
"C"
],
"percentageMatch": 100,
"matchingSkillsNames": [
"SQL",
"C"
],
"missingSkills": []
},
For the pagination, you need to pass the page
and size
form the front end
$sort
to sort the documents,$skip
skip the documents. For eg : if you are in page two and u need 10 rows , u need to skip first 10 documents$limit
to how many documents you need to show after skiphere is the code
db.collection.aggregate([
{
$sort: {
_id: 1
}
},
{
$skip: 0 // page*size
},
{
$limit: 10 // size
}
])
Working Mongo playground
More than, the pagination requires total elements too, for that
db.collection.aggregate([
{
"$facet": {
"elements": [
{
"$group": {
"_id": null,
"count": { "$sum": 1 }
}
}
],
"data": [
{ $sort: { _id: 1 } },
{ $skip: 0 }, // page*size
{ $limit: 10 } // size
]
}
},
{ "$unwind": "$elements" },
{
"$addFields": {
"elements": "$$REMOVE",
"totalRecords": "$elements.count"
}
}
])
Working Mongo playground