Rares Golea
Rares Golea

Reputation: 41

MongoDB count and results

I would really appreciate if someone could help me with something: I need to make a normal query to the database but, as my collection is very large (10000 documents) I need to do the query and use $limit and $skip. That part I solved but now I want to have a count to all the documents, even if the returned ones are less. The output should be something like this:

{
     count: 1150,
     data: [/*length of 50*/]
}

Could anyone help please? Thank you very much.

Upvotes: 3

Views: 4593

Answers (4)

Vibhu Tewary
Vibhu Tewary

Reputation: 292

You can do this using one query itself. In Node.js and Express.js, you will have to use it like this to be able to use the "count" function along with the toArray's "result".

var curFind = db.collection('tasks').find({query});

Then you can run two functions after it like this (one nested in the other)

curFind.count(function (e, count) {    
// Use count here    
    curFind.skip(0).limit(10).toArray(function(err, result) {    
    // Use result here and count here    
    });
});

Upvotes: 1

Sarath Nair
Sarath Nair

Reputation: 2868

Since you mentioned you are making a normal query, its not wise to go for aggregation. find() will be a much better option here. Instead you can use the find query itself. The commands to do this in mongoDB console is shown below:

> var docs = db.collection.find().skip(10).limit(50)
> docs.count()
189000
> docs.length()
50

Upvotes: 6

Shashank Agrawal
Shashank Agrawal

Reputation: 25797

I don't think it is possible in a single query to get the total count of the result along with the paginated data without using aggregation.

You can probably achieve this via aggregation but since you mentioned, your collection is very large, you should avoid it and break the query into two parts. I'm providing you an example of considering user collection having a rating field with more than 10,000 records:

var finalResult = {};

var query = {
    rating: {$gt: 2}
};

// Get first 50 records of users having rating greater than 2
var users = db.user.find(query).limit(50).skip(0).toArray();
// Get total count of users having rating greater than 2
var totalUsers = db.user.cound(query);

finalResult.count = totalUsers;
finalResult.data = users;

And your final output can be like:

finalResult == {
     count: 1150,
     data: [/*length of 50 users*/]
}

Hope, this make sense to you. Some of the famous technologies like Grails internally do that to achieve pagination.

Another cleaner approach could be:

var finalResult = {};

var query = {
    rating: {$gt: 2}
};

var cursor = db.user.find(query).limit(50).skip(0);
// Get total count of users having rating greater than 2
// By default, the count() method ignores the effects of the cursor.skip() and cursor.limit()    
finalResult.count = cursor.count();;
finalResult.data = cursor.toArray();

Upvotes: 0

mcmartins
mcmartins

Reputation: 1

As mentioned by Sarath Nair you can use count, as it ignores skip and limit. Check: MongoDB Count

By the way, this is duplication from another StackOverflow question: Limiting results in MongoDB but still getting the full count?

Upvotes: -1

Related Questions