Last active
January 16, 2019 03:11
-
-
Save maumercado/53d4817952b1ceccff32 to your computer and use it in GitHub Desktop.
batchinate or pagination by batches
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require('rootpath')(); | |
var mongoose = require('mongoose'); | |
var async = require('async'); | |
var _ = require('lodash'); | |
var Query = mongoose.Query; | |
Query.prototype._batchinate = function(options, callback) { | |
var query = this; | |
var model = query.model; | |
model.count(query._conditions, function (err, itemCount){ | |
query.limit(options.count).exec(function(err, results) { | |
if (err) { | |
callback(err, {}); | |
return; | |
} | |
results = results || []; | |
if (results[results.length - 1]) { | |
var maxId = (results[results.length - 1])[options.criteria.split(".")[0]][options.criteria.split(".")[1]] || (results[results.length - 1])[options.criteria]; | |
if (typeof maxId === 'object') maxId = maxId._id; | |
} else { | |
var maxId = null; | |
} | |
itemsRemaining = itemCount - results.length; | |
var pager = { | |
'count': parseInt(options.count, 10), | |
'results': results, | |
'itemsRemaining': itemsRemaining < 0 ? 0 : itemsRemaining, | |
'maxId': maxId, | |
'sinceId': options.sinceId || null | |
}; | |
if (pager['maxId'] === null) { | |
delete pager['maxId']; | |
} | |
if (pager['sinceId'] === null) { | |
delete pager['sinceId']; | |
} | |
callback(null, pager); | |
}); | |
}); | |
}; | |
Query.prototype.batchinate = function(options, callback) { | |
var defaults = { | |
sortBy : { '_id' : -1 }, // Field to sort by | |
sinceId : null, // Offset by this object | |
maxId : null, // Offset by this object | |
count : 20, // Number of items to display on each page. | |
criteria : "_id", // To find documents that match a set of selection criteria. | |
}; | |
options = options || defaults; | |
if (options.sortBy) { | |
var sortFields = options.sortBy.split(","); | |
options.sortBy = {}; | |
sortFields.forEach(function(sortedValue) { | |
options.sortBy[sortedValue] = -1; | |
}) | |
} else { | |
options.sortBy = defaults.sortBy; | |
} | |
options.sinceId = options.sinceId || defaults.sinceId; | |
options.maxId = options.maxId || defaults.maxId; | |
if(options.count > 100){ | |
options.count = 100; | |
} | |
options.count = options.count || defaults.count; | |
options.criteria = options.criteria || defaults.criteria; | |
// Initializing query object | |
options.objectQuery = {}; | |
options.objectQueryMax = {}; | |
options.objectQuerySince = {}; | |
if (options.sinceId) options.objectQuerySince[options.criteria] = options.sinceId; | |
if (options.maxId) options.objectQueryMax[options.criteria] = options.maxId; | |
// ####### | |
var query = this; | |
var model = query.model; | |
if (!_.isEmpty(options.maxId) && !_.isEmpty(options.sinceId)) { | |
async.parallel( | |
[ | |
function (p_cb) { | |
model.findOne(options.objectQueryMax, function (err, object) { | |
if (err) p_cb(err); | |
if (object) { | |
p_cb(null, object); | |
} else { | |
p_cb(null, {}); | |
} | |
}); | |
}, | |
function (p_cb) { | |
model.findOne(options.objectQuerySince, function (err, object) { | |
if (err) p_cb(err); | |
if (object) { | |
p_cb(null, object); | |
} else { | |
p_cb(null, {}); | |
} | |
}); | |
} | |
], | |
function (err, objects) { | |
if (err) query.sort(options.sortBy)._batchinate(options, callback) | |
if (objects) { // first object is the maxId object, second object is the sinceId object | |
Object.keys(options.sortBy).forEach(function (value) { | |
from_object_sortable = objects[0].model ? objects[0][value] : {}; | |
since_object_sortable = objects[1].model ? objects[1][value] : {}; | |
query.find() | |
.where(value).lt(from_object_sortable).gt(since_object_sortable) | |
.sort(options.sortBy)._batchinate(options, callback); | |
}); | |
} | |
} | |
); // end async parallel | |
} else if (!_.isEmpty(options.maxId) || !_.isEmpty(options.sinceId) ) { | |
options.objectQuery = options.maxId ? options.objectQueryMax : options.objectQuerySince; // query builder | |
model.findOne(options.objectQuery, function (err, object) { | |
if (err) { | |
callback(err, {}); | |
return; | |
} | |
if (object) { | |
if ( !_.isEmpty(options.maxId) ) { | |
Object.keys(options.sortBy).forEach(function (value) { | |
query.where(value).lt(object[value]); | |
}); | |
} else { | |
Object.keys(options.sortBy).forEach(function (value) { | |
query.where(value).gt(object[value]); | |
}); | |
} | |
query.sort(options.sortBy)._batchinate(options, callback) | |
} else { | |
query.sort(options.sortBy)._batchinate(options, callback) | |
} | |
}); | |
} else { | |
query.sort(options.sortBy)._batchinate(options, callback) | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment