Reputation: 747
$match
multiple times to get
proper result after aggregate. total_pages
in metadata, How to implement this formula Math.ceil(total_items/limit)
.Note: The code is working properly but need to optimize the logic.
db.collection('cms_brands').aggregate([
{
$facet: {
data: [{ $match: {title:"clue brand"} }, { $skip: 0 }, { $limit: 10 }],
metadatax: [ { $count: "total" }, { $addFields: { page: 0 } }],
metadata: [ { $match: {title:"clue brand"} }, { $skip: 0 }, { $limit: 10 }, {$group: { _id: "$title", count: { $sum: 1 } }} ],
}
}
]).toArray()
.then((items) => { return { statusCode: 200, body: items }; })
.catch(err => {
console.log('=> an error occurred: ', err);
return { statusCode: 500, body: 'error' };
});
Actual response :
[
{
"data": [
{
"_id": "5e91d2c4a3fda138bcdbfd82",
"title": "clue brand"
},
{
"_id": "5e91d2dea3fda138bcdbfd83",
"title": "clue brand"
}
],
"metadatax": [
{
"total": 3,
"page": 0
}
],
"metadata": [
{
"_id": "clue brand",
"count": 2
}
]
}
]
Expected response :
[
{
"data": [
{
"_id": "5e91d2c4a3fda138bcdbfd82",
"title": "clue brand"
},
{
"_id": "5e91d2dea3fda138bcdbfd83",
"title": "clue brand"
}
],
"metadata": [
{
"total": 3,
"page": 0,
"_id": "clue brand",
"count": 2
}
]
}
]
Upvotes: 1
Views: 2563
Reputation: 17915
You can change few things, try below query :
db.collection.aggregate([
{
$facet: {
metadatax: [{ $count: "total" }, { $addFields: { page: 0 } }],
metadata: [
{ $match: { title: "clue brand" } },
{ $skip: 0 },
{ $limit: 10 },
{
$group: {
_id: "$title",
count: { $sum: 1 },
data: { $push: "$$ROOT" }
}
}
]
}
},
{ $unwind: "$metadata" },
{
$project: {
data: "$metadata.data",
metadata: {
$mergeObjects: [
{ _id: "$metadata._id", count: "$metadata.count",total_pages: { $ceil: { $divide: [ { $arrayElemAt: [ "$metadatax.total", 0 ] } , 8 ] } } },
{ $arrayElemAt: ["$metadatax", 0] }
]
}
}
}
]);
Test : MongoDB-Playground
Updates :
data: [{ $match: {title:"clue brand"} }, { $skip: 0 }, { $limit: 10 }]
additional step in $facet
, can be replaced with data: { $push: "$$ROOT" }
in $group
of metadata
.metadata
will always be an array of single object - instead of being an array, I would suggest it to be an object for easy access in code. Just in case if you need it as an array all you need is to wrap $mergeObjects
in array in $project
.Like this :
metadata: [{
$mergeObjects: [
{ _id: "$metadata._id", count: "$metadata.count" },
{ $arrayElemAt: ["$metadatax", 0] }
]
}]
Upvotes: 2