Reputation: 1319
I want to implement pagination on a website and I'd like my mongodb query to return first perform the lookup between 2 collections, sort the documents, calculate the total number of documents and then return the relevant documents after $skip
and $limit
stages in the aggregation. This is my query:
const res = await Product.aggregate([
{
$lookup: {
from: 'Brand',
localField: 'a',
foreignField: 'b',
as: 'brand'
}
},
{
$sort: {
c: 1,
'brand.d': -1
}
},
{
$skip: offset
},
{
$limit: productsPerPage
}
])
I don't want to make 2 queries which are essentially the same only for the first one to return the count of documents and for the other to return the documents themselves.
So the result would be something like this:
{
documents: [...],
totalMatchedDocumentsCount: x
}
such that there will be for example 10 documents
but totalMatchedDocumentsCount
may be 500
.
I can't figure out how to do this, I don't see that aggregate
method returns cursor. Is it possible to achieve what I want in one query?
Upvotes: 1
Views: 593
Reputation: 49945
You need $facet and you can run your pipeline with $limit
and $skip
as one subpipeline while $count
can be used simultaneously:
const res = await Product.aggregate([
// $match here if needed
{
$facet: {
documents: [
{
$lookup: {
from: 'Brand',
localField: 'a',
foreignField: 'b',
as: 'brand'
}
},
{
$sort: {
c: 1,
'brand.d': -1
}
},
{
$skip: offset
},
{
$limit: productsPerPage
}
],
total: [
{ $count: "count" }
]
}
},
{
$unwind: "$total"
}
])
Upvotes: 2