Convert query string parameters into mongo query filter and options.
npm install qs-to-mongo




Thanks to this package, you can parse and convert query parameters into MongoDB query criteria and options.
npm install qs-to-mongotypescript
import qs2m from 'qs-to-mongo' // or const qs2m = require('qs-to-mongo')
const result = qs2m('name=john&age>21&fields=name,age&sort=name,-age&offset=10&limit=10')
`
The result will be
`typescript
{
criteria: {
name: 'john',
age: { $gt: 21 }
},
options: {
fields: { name: true, age: true },
sort: { name: 1, age: -1 },
offset: 10,
limit: 10
}
}
`Resulting object props (
criteria and options) are usable as parameters for any MongoDB driver or ODM. For example:
`typescript
import qs2m from 'qs-to-mongo'
import { MongoClient } from 'mongodb';(async function() {
const { db } = await MongoClient.connect(connectionString)
const result = qs2m('name=john&age>21&fields=name,age&sort=name,-age&offset=10&limit=10')
const documents = await db('dbName')
.collection('collectionName')
.find(result.criteria, result.options)
})().catch(console.log)
`API
$3
`typescript
qs2m(query: string, options: {
ignoredFields?: string | string[]
parser?: {
parse(query: string, options?: any): any
stringify(obj: object, options?: any): string
}
parserOptions?: object
dateFields?: string | string[]
objectIdFields?: string | string[]
fullTextFields?: string | string[]
parameters?: Partial
maxLimit?: number
})
`$3
* ignoredFields: array of query parameters that are ignored, in addition to default ones: "fields", "omit", "sort", "offset", "limit", "q";
* parser: custom query parser, must implement parse(query: string, options?: any): any and stringify(obj: object, options?: any): string. The default parser is qs;
* parserOptions: options to pass to the query parser;
* dateFields: fields that will be converted to Date. If no fields are passed, any valid date string will be converted to ISOString;
* objectIdFields: fields that will be converted to ObjectId;
* fullTextFields: fields that will be used as criteria when passing the q query parameter;
* parameters: override default parameters used as query options ("fields", "omit", "sort", "offset", "limit", "q"). For example: {fields:'$fields', omit:'$omit', sort:'$sort', offset:'$offset', limit:'$limit'};
* maxLimit: maximum limit that could be passed to the limit option.$3
`typescript
{
criteria: {
[key: string]: any
}
options: {
projection: {
[key: string]: 0 | 1
}
sort: {
[key: string]: 1 | -1
}
skip: number
limit: number
}
links: (url: string, totalCount: number) => {
prev: string
first: string
next: string
last: string
} | null
}
`$3
`typescript
import qs2m from 'qs-to-mongo' //or const qs2m = require('qs-to-mongo')
const query = qs2m('name=john&age>21&offset=20&limit=10')
query.links('http://localhost/api/v1/users', 100)
`
This will generate an object that could be used by the Express res.links(http://expressjs.com/en/4x/api.html#res.links) method.
`typescript
{ prev: 'http://localhost/api/v1/users?name=john&age%3E21=&offset=10&limit=10',
first: 'http://localhost/api/v1/users?name=john&age%3E21=&offset=0&limit=10',
next: 'http://localhost/api/v1/users?name=john&age%3E21=&offset=30&limit=10',
last: 'http://localhost/api/v1/users?name=john&age%3E21=&offset=90&limit=10' }
`$3
Any query parameters other than the special parameters _fields_, _omit_, _sort_, _offset_, _limit_, and _q_ are interpreted as query criteria. For example name=john&age>21 results in a _criteria_ value of:`
{
'name': 'john',
'age': { $gt: 21 }
}
`* Supports standard comparison operations (=, !=, >, <, >=, <=).
* Numeric values, where
Number(value) != NaN, are compared as numbers (i.e., field=10 yields {field:10}).
* Values of _true_ and _false_ are compared as booleans (ie. {field: true})
* ObjectId hex strings can be compared as ObjectId instances if objectIdFields` is passed.
* Values that are dates are compared as dates (except for YYYY, which matches the number rule) if dateFields is passed. If not, they will be converted to Date ISOString.
* null values are compared as null. For example bar=null yields {bar: null}
* special q query parameter could be used to perform a full-text search on fields passed in the fullTextFields argument.
* Multiple equals comparisons are merged into a $in operator. For example, id=a&id=b yields {id:{$in:['a','b']}}.
* Multiple not-equals comparisons are merged into a $nin operator. For example, id!=a&id!=b yields {id:{$nin:['a','b']}}.
Comma-separated values in equals or not-equals yield an $in or $nin operator. For example, id=a,b yields {id:{$in:['a','b']}}.name=/^john/i yields {id: /^john/i}.foo&bar=10 yields {foo: {$exists: true}, bar: 10}.!foo&bar=10 yields {foo: {$exists: false}, bar: 10}.foo:type=string, yeilds { foo: {$type: 'string} }.field='10' or field="10") would force a string compare. Allows for a string with an embedded comma (field="a,b") and quotes (field="that's all folks").foo.bar=value instead of foo[bar]=value) 'extended' syntax.Although exact matches are handled for either method, comparisons (such as foo[bar]!=value) are not supported because the qs parser expects an equals sign after the nested object reference; if it's not an equals, the remainder is discarded.
``typescript
const parameters = {
fields:'$fields',
omit:'$omit',
sort:'$sort',
offset:'$offset',
limit:'$limit',
q: '$q',
}
const query = q2m(res.query, { parameters: parameters });
`
This will then interpret the default parameters as query parameters instead of options. For example a query of age>21&omit=false&$omit=a results in a _criteria_ value of:
`typescript`
query.criteria = {
'age': { $gt: 21 },
'omit': false
}
and an _option_ value of:
`typescript`
query.option = {
fields: { a: false }
}
`typescript`
const querystring = require('querystring')
const qs2m = require('qs-to-mongo')
const query = 'name=john&age>21&fields=name,age&sort=name,-age&offset=10&limit=10'
const q = q2m(querystring.parse(query))
This makes it easy to use it in fastify route:
`typescript`
fastify.get('/api/v1/mycollection', (req, reply) =>{
const q = q2m(req.query);
...
}`
or in express one:typescript`
router.get('/api/v1/mycollection', function(req, res, next) {
const q = q2m(res.query);
...
}
The format and names for query parameters were inspired by this article about best practices for RESTful APIs.
This package started as a hard fork of https://github.com/pbatey/query-to-mongo. This is a TypeScript port, with some fixes and many improvements. However, this is not a drop-in replacement because of the changes to the public API.
and ObjectId hex string values
* adds passing options to parser with parserOptions parameter
* adds support for fulltext search on predefined fields (using fullTextFields parameter)
* opt-ins date-string conversion to Date with dateFields parameter
* opt-ins hexstring ObjectId parsing with objectIdFields parameter
* renames keywords parameter to parameters
* renames ignore to ignoredFields
* renames fields to projection` in returnd mongo optionsMIT