mongoose-advanced-query-string
Query any Model, quickly, dynamically and with a lot of options without writing code related to collections.
It helps making advanced query strings that uses mongoose queries: find()
and aggregate()
, and gives the possibility to use and chain dynamic
filtering
, sorting
, projecting
and paginating
using query strings.
It handles query strings containing: fields
, sort
, limit
and page
keywords and filter
keywords like: gt
, gte
, lt
and lte
.
Installation
$ npm install mongoose-advanced-query-string
Usage
const ApiFeatures = ; // for Find() queriesconst AggregateFeatures = ; // for Aggregate queries // 1) Example of ApiFeature Call on a mongoose "Model". const features = Model reqquery ; // Await the query to execute it and get the result.const docs = await featuresquery; /***********************************************************//***********************************************************/// 2) Example of AggregateFeature Call on a mongoose "Model".const aggFeatures = Model reqquery ; // Await the query to execute it and get the result.const docs= await aggFeaturesaggregate;
Features
Dynamic querying a mongoose model with a query string, just by chaining functions, and they can be used with any Mongoose.Model.
ApiFeatures:
Here, the ApiFeatures
constructor takes as first argument: Model.find()
which is a query Mongoose query object. The second parameter is the query object that comes with the request (req.query
).
Available functions that can be chained in any order: filter
, sort
, limiFields
, paginate
const myQuery = Model; // const features = myQuery reqquery ; // Await the query to execute it and get the result.const docs = await featuresquery;
AggregateFeatures:
Available functions that can be chained in any order: sort
, limiFields
, paginate
const myAggregation = Model; // const aggFeatures = myAggregation reqquery ; // Await the query to execute it and get the result.const docs= await aggFeaturesaggregate;
Details
Examples will be given, using a simple endpoint: Thread. It represents a simple thread model of a blog, having as fields: name, slug, type, members, online...
URL/threads //endpoints that gives all existing threads in database (triggers Thread.find()).
filter() : available only with Find()
Allows to filter documents, by the fields of the collection included in the query string. Example: domain.com/api/users?age=25&city=New+York
.
- Equality
request?field=value
; - Greater than/Greater than or equal
request?field[gt]=value
request?field[gte]=
; - Lesser than/Lesser than or equal
request?field[lt]=value
request?field[lte]=
;
const ApiFeatures = ; const features = Model reqquery; // Get threads that correspond to the query string.const threads = await featuresquery;
Query string:
{{URL}}/threads?type=show // find all threads with type equals "show".{{URL}}/threads?members[gte]=500&type=game // find threads with members count >= 500 AND type equals "game".{{URL}}/threads?online[lt]=230&type=movie // find threads with curently online members <= 230 AND type equals "game".
sort(defaultSort):
Allows to sort the result in ascending/descending order, if "sort" parameter is included in the query string. If not, defaultSort
is the default sort fields (can be separated by comma).
- Asc:
request?sort=field
- Desc:
request?sort=-field
- Multiple sort:
request?sort=field1,field2,-field3
const ApiFeatures = ; // for Find() queriesconst AggregateFeatures = ; // for Aggregate queries const features = Model reqquery; // will sort depending on the sort parameter in the query string.//ORconst features = Model reqquery; // If no "sort" parameter, will sort by createdAt in descending order. // Get threads that correspond to the query string.const threads = await featuresquery;
Query string:
{{URL}}/threads?sort=postedAt // sort threads with postedAt in ascending order.{{URL}}/threads?type=show&sort=members // find all threads with type equals "show" and sort by members number in descending order.{{URL}}/threads?type=game&sort=-postedAt,-members // find threads with type equals "game", and sort by "posted at" first, then in case of equality, will sort by "members number".
limitFields(...defaultExcludedFields):
Allows to do a project
on the resulting set. In other words, it allows to select what fields to output in result. It handles "projection" if "fields" parameter is used in the query string.
...defaultExcludedFields
: A list of default fields to be excluded if no "fields" is specified in the query sting
- Select fields:
request?fields=field1,field2,field3
: Will output a result with only "field1 field2 and field3" in the result. - Select All except:
request?fields=-field1,-field2...
: Will output a result with all the fields except for "field1 and field2" in the result.
const ApiFeatures = ; // for Find() queriesconst AggregateFeatures = ; // for Aggregate queries const features = Model reqquery; // will sort depending on the sort parameter in the query string.//ORconst features = Model reqquery; // If no "fields" parameter, will exclude by default from the result __v and _id. // Get threads that correspond to the query string.const threads = await featuresquery;
Query string:
{{URL}}/threads?fields=-postedAt,-__v // will exclude "postedAt" and "__v" from the result.{{URL}}/threads?fields=postedAt,__v // will select only "postedAt" and "__v" in the result.
N.B: Mixed values are not accepted.
paginate(defaultPage = 1, defaultLimit = 100)
Allow to do a get a subset of the resulting set, depending on the parameters used. It takes as parameters: page
and limit
.
- Select fields:
request?page=2&limit=10
: Will output a result with values starting from the 11th element to the 20th. (Starts at page 2, not 1).
const ApiFeatures = ; // for Find() queriesconst AggregateFeatures = ; // for Aggregate queries const features = Model reqquery; // will sort depending on the sort parameter in the query string.//ORconst features = Model reqquery; // If no "page" and "limit" parameters, will use pagination with inputted parameters. // Get threads that correspond to the query string.const threads = await featuresquery;
Query string:
{{URL}}/threads // will use pagination by default, where "page = 1" and "limit = 100"{{URL}}/threads?page=2&limit=20 // will use pagination with "page = 2" and "limit = 20", i.e: documents from 21 to 40.
Contributing
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change or add.
I'm open to optimize the project as much as it could be.
License
ISC