Search code examples
node.jsmongodbmongoosedaoservice-layer

How to use Mongoose skip and limit function in service layer?


How do I get a document list from DAO and perform skip, limit operations in the service layer?

This is my DAO function.

function findAllPosts(first,second) {
    return Post.find({});
}

Here is my service layer.

function findAllPosts(first, second) {
    return new Promises((resolve, reject) => {
        postDao.findAllPosts(Number(first), Number(second)).
            then((data) => {
                var sortingOrd = { 'createdAt': -1 };
            resolve(data.sort(sortingOrd).skip(Number(first)).limit(Number(second)));
            })
            .catch((error) => {
                reject(error);
            });
    });
}

I am getting this error.

TypeError: data.sort(...).skip is not a function

This is the model.

    const mongoose = require('mongoose');

var timestamps = require('mongoose-timestamp');
var mexp = require('mongoose-elasticsearch-xp');
var updateIfCurrentPlugin = require('mongoose-update-if-current').updateIfCurrentPlugin;

var PostSchema = new mongoose.Schema({
    title: String,
    content: String,
    categoryId: String,
    location: String,
    postSummary: String,
    postImage: String,
    userId: String,
    author: String,
    urlToImage: String,
    newsSrc: String
});

PostSchema.plugin(mexp);
PostSchema.plugin(updateIfCurrentPlugin);

PostSchema.plugin(timestamps);
var Post = mongoose.model('Post', PostSchema);

Post
    .esCreateMapping(
        {
            "analysis": {
                "analyzer": {
                    "my_custom_analyzer": {
                        "type": "custom",
                        "tokenizer": "standard",
                        "char_filter": [
                            "html_strip"
                        ],
                        "filter": [
                            "lowercase",
                            "asciifolding"
                        ]
                    }
                }
            }
        }
    )
    .then(function (mapping) {
        // do neat things here
    });

Post.on('es-bulk-sent', function () {
});

Post.on('es-bulk-data', function (doc) {
});

Post.on('es-bulk-error', function (err) {
});

Post
    .esSynchronize()
    .then(function () {
    });

module.exports = Post;

I removed sort, skip and limit from DAO layer for a specific purpose. Can you tell me how to use these in the service layer? Is there an explicit way of casting the "data" array to a DocumentQuery object?


Solution

  • The problem is inside of findAllPosts function. If you need to skip or limit, you should handle them inside of your function.

    function findAllPosts(first,second, skip, limit) {
        return Post.find({}).skip(skip).limit(limit);
    }
    

    Or completely remove findAllPosts function and directly use Post.find().limit().skip() inside of your main logic.

    My recommendation: Implement an independent single-purpose function to return your response:

    function findAllPosts(query, options, cb) {
        Post
        .find(query)
        .select(options.select)
        .skip(options.skip)
        .limit(options.limit)
        .sort(options.sort)
        .lean(options.lean)
        .exec(function(err, docs {
          if(err) return cb(err, null);
    
          return cb(null, docs);
        });
    }