diff --git a/caracal.js b/caracal.js index e17323f..2e646c5 100644 --- a/caracal.js +++ b/caracal.js @@ -75,6 +75,7 @@ var HANDLERS = { }, "monitorCheck": monitor.check, "mongoFind": dataHandlers.General.find, + "mongoPaginatedFind": dataHandlers.General.paginatedFind, "mongoFindWithRegex": dataHandlers.General.findWithRegex, "mongoAdd": dataHandlers.General.add, "mongoUpdate": dataHandlers.General.update, diff --git a/handlers/dataHandlers.js b/handlers/dataHandlers.js index b345aaf..4e69192 100644 --- a/handlers/dataHandlers.js +++ b/handlers/dataHandlers.js @@ -13,6 +13,16 @@ General.find = function(db, collection) { }; }; +General.paginatedFind = function(db, collection) { + return function(req, res, next) { + var query = req.query; + mongoDB.paginatedFind(db, collection, query).then((x) => { + req.data = x; + next(); + }).catch((e) => next(e)); + }; +}; + General.count = function(db, collection) { return function(req, res, next) { var query = req.query; diff --git a/service/database/index.js b/service/database/index.js index 8692d7b..e4bdefd 100644 --- a/service/database/index.js +++ b/service/database/index.js @@ -24,10 +24,7 @@ class Mongo { query = transformIdToObjectId(query); const collection = getConnection(database).collection(collectionName); - let { _page = 0, _pageSize = 1000, ...filterQuery } = query; - const _skip = _page * _pageSize; - _pageSize = parseInt(_pageSize, 10); - const data = await collection.find(filterQuery).skip(_skip).limit(_pageSize).toArray(); + const data = await collection.find(query).toArray(); /** allow caller method to toggle response transformation */ if (transform) { @@ -45,6 +42,44 @@ class Mongo { } } + /** + * Runs the MongoDB find() method to fetch documents with pagination. + * + * @async + * @param {string} database Name of the database + * @param {string} collectionName Name of the collection to run operation on + * @param {document} query Specifies selection filter using query operators. + * To return all documents in a collection, omit this parameter or pass an empty document ({}). + * @param {boolean} [transform=false] check to transform the IDs to ObjectID in response + * + * {@link https://docs.mongodb.com/manual/reference/method/db.collection.find/ Read MongoDB Reference} + */ + static async paginatedFind(database, collectionName, query, transform = true) { + try { + query = transformIdToObjectId(query); + + const collection = getConnection(database).collection(collectionName); + let { _page = 0, _pageSize = 1000, ...filterQuery } = query; + const _skip = _page * _pageSize; + _pageSize = parseInt(_pageSize, 10); + const data = await collection.find(filterQuery).skip(_skip).limit(_pageSize).toArray(); + + /** allow caller method to toggle response transformation */ + if (transform) { + data.forEach((x) => { + x["_id"] = { + $oid: x["_id"], + }; + }); + } + + return data; + } catch (e) { + console.error(e); + throw e; + } + } + /** * Runs the MongoDB count() method to count documents. * @@ -232,6 +267,7 @@ class Mongo { module.exports = { add: Mongo.add, find: Mongo.find, + paginatedFind: Mongo.paginatedFind, update: Mongo.update, delete: Mongo.delete, aggregate: Mongo.aggregate,