mongodb-paginate
Advanced tools
Comparing version 1.0.1 to 1.1.0
@@ -39,6 +39,6 @@ "use strict"; | ||
Object.defineProperty(exports, "mongoDB", { enumerable: true, get: function () { return mongopool_1.mongoDB; } }); | ||
const paginate = function (collection, prePagingStage, postPagingStage, options, facet) { | ||
const paginate = function (collection, prePagingStage, postPagingStage, options, facet, aggregateOptions) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
let db = yield mongopool_1.default.getDB(); | ||
let { sort: sortOption, page: pageOption, limit: limitOption, sortOrder, fetchAll } = options; | ||
let { sort: sortOption, page: pageOption, limit: limitOption, sortOrder = -1, fetchAll } = options; | ||
//defaults | ||
@@ -52,13 +52,7 @@ let sort; | ||
} | ||
if (sortOrder === 1) { | ||
sortOrder = 1; | ||
} | ||
else | ||
sortOrder = -1; //default 1 | ||
let limit = (limitOption && isFinite(limitOption) && limitOption > 0) ? limitOption : 50; //default limit is 50 | ||
let page = pageOption && isFinite(pageOption) ? pageOption : 1; //default first page | ||
let aggregatePipeLine = []; | ||
const aggregatePipeLine = []; | ||
aggregatePipeLine.push(...prePagingStage); | ||
//sort, skip, limit | ||
let sortStage = [ | ||
const sortStage = [ | ||
{ $sort: { [sort]: sortOrder, _id: 1 } } | ||
@@ -79,3 +73,3 @@ ]; | ||
postPagingStage.forEach((item, index) => { | ||
if (item['$group'] || item['$replaceRoot']) | ||
if ("$group" in item || "$replaceRoot" in item) | ||
groupIndex = index; | ||
@@ -99,3 +93,12 @@ }); | ||
aggregatePipeLine.push({ $facet: facetStage }); | ||
let aggregateResult = yield db.collection(collection).aggregate(aggregatePipeLine).toArray(); | ||
let aggregateResult; | ||
if (typeof collection === "string") { | ||
aggregateResult = yield db.collection(collection).aggregate(aggregatePipeLine, aggregateOptions).toArray(); | ||
} | ||
else if (collection instanceof mongopool_1.mongoDB.Collection) { | ||
aggregateResult = yield collection.aggregate(aggregatePipeLine, aggregateOptions).toArray(); | ||
} | ||
else { | ||
aggregateResult = yield collection.aggregate(aggregatePipeLine, aggregateOptions).exec(); | ||
} | ||
let result = aggregateResult[0]; | ||
@@ -102,0 +105,0 @@ if (!result || !result["page"] || !result["page"][0]) |
import { mongoDB } from "@imtiazchowdhury/mongopool"; | ||
import mongoose, { PipelineStage } from "mongoose"; | ||
export interface PaginationOptions { | ||
@@ -20,3 +21,3 @@ sort?: string; | ||
sort: string; | ||
sortOrder: number; | ||
sortOrder: 1 | -1; | ||
}; | ||
@@ -29,2 +30,2 @@ data: mongoDB.Document[]; | ||
} | ||
export type Paginate = (collection: string, prePagingState: mongoDB.Document[], postPagingStage: mongoDB.Document[], options: PaginationOptions, facet: FacetBucketQuery[]) => Promise<mongoDB.Document>; | ||
export type Paginate = (collection: string | mongoose.Model<mongoDB.Document> | mongoDB.Collection, prePagingState: PipelineStage[], postPagingStage: PipelineStage[], options: PaginationOptions, facet?: FacetBucketQuery[], aggregateOptions?: mongoDB.AggregateOptions) => Promise<mongoDB.Document>; |
{ | ||
"name": "mongodb-paginate", | ||
"version": "1.0.1", | ||
"version": "1.1.0", | ||
"description": "mongodb aggregation with pagination library for efficient and fast aggregations", | ||
@@ -14,3 +14,4 @@ "main": "dist/index", | ||
"dependencies": { | ||
"@imtiazchowdhury/mongopool": "^1.4.0" | ||
"@imtiazchowdhury/mongopool": "^1.5.1", | ||
"mongoose": "^8.0.0" | ||
}, | ||
@@ -17,0 +18,0 @@ "devDependencies": { |
185
readme.md
# Mongodb Paginate | ||
Generate pagination data with mongodb aggregation and optimize aggregation performance. | ||
Generate pagination data with raw mongodb/mongoose aggregation and optimize aggregation performance. | ||
@@ -27,2 +27,6 @@ ## installation | ||
can be used with raw mongodb connection, by passing mongodb collection or by passing mongoose model | ||
### raw mongodb with collection name as string | ||
```js | ||
@@ -32,2 +36,3 @@ | ||
// only required if working with raw mongodb and passed collection name as string, not required for mongoose or if passed collection instance | ||
dbConnection.url = "mongodb://127.0.0.1:27017" // YOUR DATABASE URL | ||
@@ -76,3 +81,3 @@ dbConnection.dbName = "DB_NAME" //YOUR DATABASE NAME | ||
const result = await paginate( | ||
"product", | ||
"product", //pass collection name/collection instance for raw mongodb, pass model for mongoose | ||
prePagingStage, | ||
@@ -88,2 +93,117 @@ postPagingStage, | ||
### raw mongodb with collection instance | ||
```js | ||
import paginate, { dbConnection } from "mongodb-paginate"; | ||
... | ||
const prePagingStage = [], postPagingStage = [], facet = []; | ||
//filter | ||
prePagingStage.push(...[ | ||
{ | ||
$match: { | ||
featured: true | ||
} | ||
} | ||
]) | ||
//populate | ||
postPagingStage.push({ | ||
$lookup: { | ||
from: "category", | ||
localField: "category", | ||
foreignField: "_id", | ||
as: "category" | ||
} | ||
}) | ||
//custom facet queries if needed | ||
facet.push({ | ||
key: "categoryWiseCount", | ||
query: [ | ||
{ $unwind: "$category" }, | ||
{ | ||
$group: { | ||
_id: "$category", | ||
count: { $sum: 1 }, | ||
} | ||
} | ||
] | ||
}) | ||
const pagingOptions = { page: 2, limit: 1 }; | ||
const result = await paginate( | ||
productCollection, //pass collection name/collection instance for raw mongodb, pass model for mongoose | ||
prePagingStage, | ||
postPagingStage, | ||
pagingOptions | ||
facet | ||
); | ||
... | ||
``` | ||
### Mongoose | ||
```js | ||
import paginate, { dbConnection } from "mongodb-paginate"; | ||
... | ||
const prePagingStage = [], postPagingStage = [], facet = []; | ||
//filter | ||
prePagingStage.push(...[ | ||
{ | ||
$match: { | ||
featured: true | ||
} | ||
} | ||
]) | ||
//populate | ||
postPagingStage.push({ | ||
$lookup: { | ||
from: "category", | ||
localField: "category", | ||
foreignField: "_id", | ||
as: "category" | ||
} | ||
}) | ||
//custom facet queries if needed | ||
facet.push({ | ||
key: "categoryWiseCount", | ||
query: [ | ||
{ $unwind: "$category" }, | ||
{ | ||
$group: { | ||
_id: "$category", | ||
count: { $sum: 1 }, | ||
} | ||
} | ||
] | ||
}) | ||
const pagingOptions = { page: 2, limit: 1 }; | ||
const result = await paginate( | ||
ProductModel, //pass collection name/collection instance for raw mongodb, pass model for mongoose | ||
prePagingStage, | ||
postPagingStage, | ||
pagingOptions | ||
facet | ||
); | ||
... | ||
``` | ||
the above query will generate a response similar to the following: | ||
@@ -113,3 +233,4 @@ | ||
"title": "Motorized treadmill 2.0hp with free massager - Walking Stick - gym equipment", | ||
"category": [ | ||
"category": [ //populated from the post-paging stage | ||
{ | ||
@@ -122,2 +243,3 @@ "_id": "64eee55cbe86262266b88871", | ||
], | ||
"price": { | ||
@@ -157,8 +279,9 @@ "regular": 42000, | ||
```ts | ||
function Paginate( | ||
collection: string, | ||
prePagingState: mongoDB.Document[], | ||
postPagingStage: mongoDB.Document[], | ||
options: PaginationOptions, | ||
facet: FacetBucketQuery[] | ||
function Paginate = ( | ||
collection: string | mongoose.Model<mongoDB.Document> | mongoDB.Collection, | ||
prePagingState: PipelineStage[], | ||
postPagingStage: PipelineStage[], | ||
options: PaginationOptions, | ||
facet?: FacetBucketQuery[], | ||
aggregateOptions?: mongoDB.AggregateOptions | ||
) => Promise<mongoDB.Document> | ||
@@ -168,30 +291,30 @@ ``` | ||
```ts | ||
PaginationOptions { | ||
sort?: string; | ||
page?: number; | ||
limit?: number; | ||
sortOrder?: 1 | -1; | ||
fetchAll?: 1 | 0; | ||
interface PaginationOptions { | ||
sort?: string, | ||
page?: number, | ||
limit?: number, | ||
sortOrder?: 1 | -1, | ||
fetchAll?: 1 | 0 | ||
} | ||
PaginateResult { | ||
interface PaginateResult { | ||
page: { | ||
totalPage: number; | ||
currentPage: number; | ||
nextPage: number; | ||
previousPage: number; | ||
startingIndex: number; | ||
endingIndex: number; | ||
itemsOnCurrentPage: number; | ||
limit: number; | ||
sort: string; | ||
sortOrder: number; | ||
}; | ||
data: mongoDB.Document[]; | ||
totalPage: number, | ||
currentPage: number, | ||
nextPage: number, | ||
previousPage: number, | ||
startingIndex: number, | ||
endingIndex: number, | ||
itemsOnCurrentPage: number, | ||
limit: number, | ||
sort: string, | ||
sortOrder: 1 | -1, | ||
}, | ||
data: mongoDB.Document[] | ||
} | ||
FacetBucketQuery { | ||
key: string; | ||
query: mongoDB.Document[]; | ||
interface FacetBucketQuery { | ||
key: string, | ||
query: mongoDB.Document[] | ||
} | ||
``` |
import dbConnection, { mongoDB } from "@imtiazchowdhury/mongopool" | ||
import { Paginate } from "./types/types"; | ||
const paginate: Paginate = async function (collection, prePagingStage, postPagingStage, options, facet) { | ||
const paginate: Paginate = async function (collection, prePagingStage, postPagingStage, options, facet, aggregateOptions) { | ||
let db = await dbConnection.getDB(); | ||
let { sort: sortOption, page: pageOption, limit: limitOption, sortOrder, fetchAll } = options; | ||
let { sort: sortOption, page: pageOption, limit: limitOption, sortOrder = -1, fetchAll } = options; | ||
@@ -18,5 +18,2 @@ //defaults | ||
if (sortOrder === 1) { | ||
sortOrder = 1; | ||
} else sortOrder = -1; //default 1 | ||
@@ -27,7 +24,8 @@ let limit = (limitOption && isFinite(limitOption) && limitOption > 0) ? limitOption : 50; //default limit is 50 | ||
let aggregatePipeLine = []; | ||
const aggregatePipeLine = []; | ||
aggregatePipeLine.push(...prePagingStage); | ||
//sort, skip, limit | ||
let sortStage = [ | ||
type SortStage = { $sort: { [index: string]: 1 | -1, _id: 1 } }[] | ||
const sortStage: SortStage = [ | ||
{ $sort: { [sort]: sortOrder, _id: 1 } } | ||
@@ -54,3 +52,3 @@ ] | ||
postPagingStage.forEach((item, index) => { | ||
if (item['$group'] || item['$replaceRoot']) groupIndex = index; | ||
if ("$group" in item || "$replaceRoot" in item) groupIndex = index; | ||
}) | ||
@@ -77,4 +75,11 @@ postPagingStage.splice(groupIndex + 1, 0, ...sortStage); | ||
let aggregateResult: mongoDB.Document[]; | ||
let aggregateResult = await db.collection(collection).aggregate(aggregatePipeLine).toArray(); | ||
if (typeof collection === "string") { | ||
aggregateResult = await db.collection(collection).aggregate(aggregatePipeLine, aggregateOptions).toArray(); | ||
} else if (collection instanceof mongoDB.Collection) { | ||
aggregateResult = await collection.aggregate(aggregatePipeLine, aggregateOptions).toArray() | ||
} else { | ||
aggregateResult = await collection.aggregate(aggregatePipeLine, aggregateOptions).exec() | ||
} | ||
@@ -113,2 +118,2 @@ let result = aggregateResult[0]; | ||
mongoDB | ||
} | ||
} |
import { mongoDB } from "@imtiazchowdhury/mongopool" | ||
import mongoose, { PipelineStage } from "mongoose" | ||
@@ -22,3 +23,3 @@ export interface PaginationOptions { | ||
sort: string, | ||
sortOrder: number, | ||
sortOrder: 1 | -1, | ||
}, | ||
@@ -35,8 +36,9 @@ data: mongoDB.Document[] | ||
export type Paginate = ( | ||
collection: string, | ||
prePagingState: mongoDB.Document[], | ||
postPagingStage: mongoDB.Document[], | ||
collection: string | mongoose.Model<mongoDB.Document> | mongoDB.Collection, | ||
prePagingState: PipelineStage[], | ||
postPagingStage: PipelineStage[], | ||
options: PaginationOptions, | ||
facet: FacetBucketQuery[] | ||
facet?: FacetBucketQuery[], | ||
aggregateOptions?: mongoDB.AggregateOptions | ||
) => Promise<mongoDB.Document> | ||
31478
10
380
313
2
+ Addedmongoose@^8.0.0
+ Added@mongodb-js/saslprep@1.2.0(transitive)
+ Addeddebug@4.4.0(transitive)
+ Addedkareem@2.6.3(transitive)
+ Addedmongoose@8.10.0(transitive)
+ Addedmpath@0.9.0(transitive)
+ Addedmquery@5.0.0(transitive)
+ Addedms@2.1.3(transitive)
+ Addedsift@17.1.3(transitive)
+ Addedwhatwg-url@14.1.1(transitive)
- Removed@mongodb-js/saslprep@1.1.9(transitive)
- Removedwhatwg-url@14.1.0(transitive)