Reputation: 1547
I'm aware there are a few questions very similar to this, but I haven't been able to find one which clearly outlines how to keep both the total count after match (in this case geoNear), but before skip/limit operations, as well as the skip/limit results.
My current aggregation pipeline is:
[ { '$geoNear':
{ near: [Object],
maxDistance: 4000,
distanceField: 'distance',
spherical: true,
query: {} } },
{ '$sort': { distance: 1 } },
{ '$skip': 0 },
{ '$limit': 20 } ]
Ideally I'd want something like this returned:
{
total: 123,
results: [<results respecting $skip & $limit>]
}
Upvotes: 2
Views: 473
Reputation: 45402
You can do :
$group
to sum result of previous $geonear
match and push the $$ROOT
document to keep the record$unwind
necessary to remove the array$skip
$limit
$group
to format the final result with only the sum amount and the JSON array Query is :
db.coll.aggregate([{
$geoNear: {
near: [Object],
maxDistance: 4000,
distanceField: 'distance',
spherical: true,
query: {}
}
}, {
$sort: {
distance: 1
}
}, {
$group: {
_id: 0,
count: {
$sum: 1
},
document: {
$push: "$$ROOT"
}
}
}, {
$unwind: "$document"
}, {
$skip: 0
}, {
$limit: 20
}, {
$group: {
_id: 0,
total: {
$first: "$count"
},
results: {
$push: "$document"
}
}
}])
You can use $slice
instead of $skip
and $limit
and preserveNullAndEmptyArrays
for the $unwind
part to assure an empty result
array :
db.coll.aggregate([{
$geoNear: {
near: [Object],
maxDistance: 4000,
distanceField: 'distance',
spherical: true,
query: {}
}
}, {
$sort: {
distance: 1
}
}, {
$group: {
_id: 0,
count: {
$sum: 1
},
document: {
$push: "$$ROOT"
}
}
}, {
$project: {
count: 1,
document: { $slice: ["$document", 0, 20] }
}
}, {
$unwind: { path: "$document", preserveNullAndEmptyArrays: true }
}, {
$group: {
_id: 0,
total: {
$first: "$count"
},
results: {
$push: "$document"
}
}
}])
Upvotes: 4