Full Article click here
This module is used to query a single MongoDB collection written with mongoose dynamically with simple query parameters using MongoDB query types 'AND' and 'OR' with MongoDB filter options eg '$gt' as 'gt', '$gte' as 'gte', '$lt' as 'lt', '$lte' as 'lte', '$eq' as 'eq' and 'cn' for case insensitive query for contains replacing MongoDB regex expression eg '/.*Will Abule.*/i' you can also write your own MongoDB queries as expressions.
The client(s) consuming your API just has to follow simple roles or better a query structure and it dynamically query and return an object as the result containing five fields data, pageSize, records, pageNumber, and total.
data representing the queried data, pageSize representing the bash of data returned, records representing the total records found based on the filter, pageNumber representing the current paginated page, and total representing the number of pages.
run npm i -s mongodb-collection-query-with-mongoose
Post model file
const mongoose = require("mongoose"); const postSchema = new mongoose.Schema({ title: { type: String, required: true, }, description: { type: String, }, imageUrl: { type: String, required: true, unique: true }, userId: { type: String }, tags: { type: Array }, date: { type: Date, required: true, default: Date.now } }); const Post = mongoose.model("Post", postSchema); module.exports.postScheama = postScheama; module.exports.Post = Post;
post route file
const getResReq = require("mongodb-collection-query-with-mongoose");router.get("/post", async (req, res) => { try { const setect = "_id title userId description imageUrl" const response = await Promise.all([getResReq(query, Post, select)]); const { data, type, msg, status } = response[0]; if (type === "error") return res .status(status) .send({ message:
internal server error
, error: msg });return res.send(data);
} catch { return res.status(500).send({ message :
internal server error
, error: data }) } });
NOTE: As a backend developer you can write your own additional query eg from v1.0.5
const searchFilter = JSON.parse(req.query.searchFilters).rules; const result = searchFilter.push({ option: "expression", filed: "tags" data: { $all: ['red', 'blank'] } })// note any mongodb query will work just specify the query at the "data" and doc field at "field " and this can also be done from the client as well if you so which.
don't install the package for reading only if your backend developer uses this library
filter (boolean): If you want the collection to filtered or not, if true the search filter is required
pageSize (number): The page size that is the number of bashes you want records to be sent
pageNumber (number): The page from the filtered collection
sortName (string): What field in the document to want the result to be sorted with eg a collection of users can be sorted by fristName
sort (string): the sort order either ascending as 'asc' or descending as 'desc'
searchFilter (string): a stringified object with the following fields: searchOption, and rules
searchOption: either 'AND' or 'OR' in uppercase. AND will return data if all search rules evaluate to true, 'OR' will return data if all one or multiple of the rules are set to true.
rules: An array of objects, each object must have the following fields
field: The document field
option: how you want it to be quired. This is to be set to either the following
cn (contains)
eq (equal)
ne (not equal)
gt (greater than)
gte (greater than or equal)
lt (less than)
lte (less than or equal)
in (in an array)
nin (not in an array)
range ( for querying data in range)
expression ( for writing your own MongoDB queries)
data: The value of the field
type: The data type of the data. it must be set to either of the following
number
float
string
date
boolean
query filter rules
cn: (contains): can only be used for string values.
eq: (equal: operator matches documents where the value of a field equals the specified value.)
ne: (not equal: selects those documents where the value of the field
is greater than (i.e. >
) the specified value
.)
gt: (greater than: selects the documents where the value of the field
is greater than or equal to (i.e. >=
) a specified value (e.g. value
.))
gte: (greater than or equal: selects the documents where the value of the field
is greater than or equal to (i.e. >=
) a specified value (e.g. value
.))
lt: (less than: selects the documents where the value of the field
is less than (i.e. <
) the specified value
.)
lte: (less than or equal: selects the documents where the value of the field
is less than or equal to (i.e. <=
) the specified value
.)
in: (operator selects the documents where the value of a field equals any value in the specified array.l)
nin: (less than or equal: operator selects the documents whose field
holds an array with no element equal to a value in the specified array (e.g. <value1>
, <value2>
, etc.).)
expression: ( for writing your own MongoDB queries)
range: this example will explain better
if I want to filter the list of posts where name is 'will' and the date is greater than the date seven days ago but less than or equal to today date. This can be written as follows
const searchFilters = { searchOption:"OR", rules:[{ field:"name", option:"cn", type:"string", data:"will" },{ field:"date", type:"range", data: [ { option:"gt", type:"data", data: new Date(new Date().setDate(new Date().getDate() - 7)) }, { option:"lte", type:"date", data: new Date() }, ] }] }
NOTE: The range type is an array with a max and min length of 2 and option and type can be omitted.
Example So if you want to query a collection of users that the name or the email contains will
const searchFilters = { searchOption:"OR", rules:[{ field:"name", option:"cn", type:"string", data:"will" },{ field:"email", option:"cn", type:"string", data:"will" }] }
if you want to query a collection of post that the title or the description contains will and userId is 1234
const searchFilters = { searchOption:"AND", rules:[{ field:"title", option:"cn", type:"string", data:"will" },{ field:"description", option:"cn", type:"string", data:"will" },{ field:"userId", option:"eq", type:"string", data:"will" }] }
if you want to sort the result in a descending by name then I will do something like this
const query = { sort : 'desc', sortName : 'title', }
if you want to the result to be filtered I will do something like this
const query = { filter : true, searchFilters : JSON.stringify(searchFilters) }
if you want the result to brought by 10 batches starting from page 1 I will do something like this
const query = { pageNumber : 1, pageSize : 10 }
so the end result will look like this
const searchFilters = { searchOption:"AND", rules:[{ field:"title", option:"cn", type:"string", data:"will" },{ field:"description", option:"cn", type:"string", data:"will" },{ field:"userId", option:"eq", type:"string", data:"will" }] }
const query = { filter : true, pageNumber : 1, pageSize : 10 sort : 'desc', sortName : 'title', searchFilters : JSON.stringify(searchFilters) }
Result for the API will look like this
Result : { data: array, pageSize: array, records: number, pageNumber: number, total: number }
data (array): The data found in the collections eg post collection
pageSize (number): The batch was returned data found in the collections eg post collection
records (number): The total records found in the collections eg post collection
pageNumber (number): The page you specified records should start from in the collections eg post collection
total (number): The number of pages in the collections eg post collection
A useful example to help you combine query
const searchFilters = { searchOption:"AND", rules:[{ field:"title", option:"cn", type:"string", data:"will" },{ field:"description", option:"ne", type:"string", data:"test" },{ field:"userId", option:"eq", type:"string", data:"will" },{ field:"tags", option:"in", // or nin type:"array", data:["is", 3, 12.2, true, new Date()] },{ field:"date", type:"range", data: [ { option:"gte", // or gt type:"data", data: new Date(new Date().setDate(new Date().getDate() - 7)) }, { option:"lte",// or lt type:"date", data: new Date() }, ] }] }