Search code examples
node.jsmongodbmongoosemongoose-populate

How to improve MongoDB performance with mongoose driver?


I have 2 collections in MongoDB.

  1. Document
  2. Data

Document has around 5K documents and getting the total count was pretty fast.

But later I added one more collection Data which has 1M records. Now if I tried to get the Total count of records in Document, its taking 20s in Mongoose. But in the Mongo Console its faster.

//Document Schema

var docSchema = mongoose.Schema({
            docId: String,
            articleid: String,
            title:String,
            lastModified: String,
});
docSchema.index({ docId: 1, articleid: 1 ,lastModified:1});
var Doc = mongoose.model('document', docSchema);

module.exports = Doc;

//Data Schema

var allData = mongoose.Schema({
    _id:String,
    id: Number,
    author:String,    
});
allData.index({ id: 1});
var data = mongoose.model('Data', allMetricsData);

module.exports = data;

And the aggregate function in Node.JS is like:

 Document.count(function(errs, count) {
   console.log("Count is:",count);
 });

So how to improve the performance with Mongoose?

When I execute, db.documents.count() I'm getting the response instantly.


Solution

  • First thing, don't forget to put index on all main fields use in your queries.

    For example if all your query use the 'name' :

    Collection.find({name: "aaa"})
    

    or 'name' and 'age' :

    Collection.find({name:"aaa", "age": 4})
    

    Put index in your model as the following :

    var mongoose = require("mongoose")
    
    ActionCode = new mongoose.Schema({
        name:                   {type: String, default: ""},
        age:                    {type:Number, default: 0},
        otherfield:             {type:Number, default: 0},
    });
    
    ActionCode.index({name:1});
    ActionCode.index({name:1, age: 1});
    
    module.exports = mongoose.model('ActionCode', ActionCode);
    

    Your index will be push into the ram, according to this the resolution of the document will be made faster.

    https://docs.mongodb.com/manual/indexes/

    Then, it can take times due to the amount of returned document, only select needed fields, like this mongo will return to your server only needed field instead of whole documents :

    Example, if you need only name, age and type field:

     Collection.find({name: "aaa"},{name:1, age:1, field:1}, function(err, response){
    
            // returned documents here contains only following fields: _id, name, age, field
    

    =======

    Try

     Collection.find({}).select({_id: 1}).count(function(err, result)
    

    Or try an aggregate :

    Collection.aggregate([{$group:{_id: null, count:{$sum :1}}])