What is mingo?
Mingo is a JavaScript library that provides MongoDB-like query and aggregation capabilities for in-memory data processing. It allows you to filter, sort, group, and transform data collections using a syntax similar to MongoDB queries.
What are mingo's main functionalities?
Querying
This feature allows you to perform complex queries on your data collections. The example demonstrates how to filter a list of people to find those older than 26.
const mingo = require('mingo');
const data = [
{ name: 'John', age: 25 },
{ name: 'Jane', age: 30 },
{ name: 'Jim', age: 27 }
];
const query = new mingo.Query({ age: { $gt: 26 } });
const result = query.find(data).all();
console.log(result); // Output: [ { name: 'Jane', age: 30 }, { name: 'Jim', age: 27 } ]
Aggregation
This feature allows you to perform aggregation operations on your data collections. The example demonstrates how to calculate the average salary of people older than 26.
const mingo = require('mingo');
const data = [
{ name: 'John', age: 25, salary: 50000 },
{ name: 'Jane', age: 30, salary: 60000 },
{ name: 'Jim', age: 27, salary: 55000 }
];
const pipeline = [
{ $match: { age: { $gt: 26 } } },
{ $group: { _id: null, averageSalary: { $avg: '$salary' } } }
];
const result = mingo.aggregate(data, pipeline);
console.log(result); // Output: [ { _id: null, averageSalary: 57500 } ]
Projection
This feature allows you to project specific fields from your data collections. The example demonstrates how to retrieve only the 'name' and 'age' fields from a list of people.
const mingo = require('mingo');
const data = [
{ name: 'John', age: 25, salary: 50000 },
{ name: 'Jane', age: 30, salary: 60000 },
{ name: 'Jim', age: 27, salary: 55000 }
];
const query = new mingo.Query({});
const result = query.find(data).project({ name: 1, age: 1 }).all();
console.log(result); // Output: [ { name: 'John', age: 25 }, { name: 'Jane', age: 30 }, { name: 'Jim', age: 27 } ]
Other packages similar to mingo
lodash
Lodash is a JavaScript utility library that provides a wide range of functions for manipulating arrays, objects, and other data structures. While it does not offer MongoDB-like query syntax, it provides similar functionalities for filtering, sorting, and transforming data collections.
underscore
Underscore is another JavaScript utility library similar to Lodash. It provides a set of utility functions for working with arrays, objects, and other data types. Like Lodash, it does not offer MongoDB-like query syntax but provides similar data manipulation capabilities.
json-query
json-query is a library for querying JSON data structures using a simple query language. It provides functionalities for filtering and transforming JSON data, similar to Mingo, but with a different query syntax.
mingo
MongoDB query language for in-memory objects

Install
$ npm install mingo
Features
For documentation on using query operators see mongodb
Browse package docs for modules.
Usage
import mingo from "mingo";
const mingo = require("mingo");
The main module exports Aggregator
, Query
, aggregate()
, find()
, and remove()
. Only Query and Projection operators are loaded by default when you require the main module. This is done using the side-effect module mingo/init/basic
and automatically includes pipeline operators; $project
, $skip
, $limit
, and $sort
.
Loading Operators
MongoDB query library is huge and you may not need all the operators. If using this library on the server-side where bundle size is not a concern, you can load all operators as shown below.
import "mingo/init/system";
Or from the node CLI
node -r 'mingo/init/system' myscript.js
To support tree-shaking for client side bundles, you can import and register specific operators that will be used in your application.
ES6
import { useOperators, OperatorType } from "mingo/core";
import { $trunc } from "mingo/operators/expression/trunc";
import { $bucket } from "mingo/operators/pipeline/bucket";
useOperators(OperatorType.EXPRESSION, { $trunc });
useOperators(OperatorType.PIPELINE, { $bucket });
ES5
const core = require("mingo/core");
const $trunc = require("mingo/operators/expression/trunc").$trunc;
const $bucket = require("mingo/operators/pipeline/bucket").$bucket;
const useOperators = core.useOperators;
const OperatorType = core.OperatorType;
useOperators(OperatorType.EXPRESSION, { $trunc: $trunc });
useOperators(OperatorType.PIPELINE, { $bucket: $bucket });
Using query to test objects
import { Query } from "mingo";
let query = new Query({
type: "homework",
score: { $gte: 50 },
});
query.test(doc);
Searching and Filtering
import { Query } from "mingo";
let criteria = { score: { $gt: 10 } };
let query = new Query(criteria);
let cursor = query.find(collection);
cursor.sort({ student_id: 1, score: -1 }).skip(100).limit(100);
cursor.count();
while (cursor.hasNext()) {
console.log(cursor.next());
}
for (let value of cursor) {
console.log(value);
}
cursor.all();
Using $jsonSchema operator
To use the $jsonSchema
operator, you must register your own JsonSchemaValidator
in the options.
No default implementation is provided out of the box so users can use a library with their preferred schema format.
The example below uses Ajv to implement schema validation.
import { RawObject } from "mingo/types"
import { JsonSchemaValidator } from "mingo/core"
import Ajv, { Schema } from "ajv"
const jsonSchemaValidator: JsonSchemaValidator = (s: RawObject) => {
const ajv = new Ajv();
const v = ajv.compile(s as Schema);
return (o: RawObject) => (v(o) ? true : false);
};
const schema = {
type: "object",
required: ["item", "qty", "instock"],
properties: {
item: { type: "string" },
qty: { type: "integer" },
size: {
type: "object",
required: ["uom"],
properties: {
uom: { type: "string" },
h: { type: "number" },
w: { type: "number" },
},
},
instock: { type: "boolean" },
},
};
find(docs, { $jsonSchema: schema }, {}, { jsonSchemaValidator }).all();
Note: An error is thrown when the $jsonSchema
operator is used without a the jsonSchemaValidator
configured.
Aggregation Pipeline
import { Aggregator } from "mingo/aggregator";
import { useOperators, OperatorType } from "mingo/core";
import { $match, $group } from "mingo/operators/pipeline";
import { $min } from "mingo/operators/accumulator";
useOperators(OperatorType.PIPELINE, { $match, $group });
useOperators(OperatorType.ACCUMULATOR, { $min });
let agg = new Aggregator([
{ $match: { type: "homework" } },
{ $group: { _id: "$student_id", score: { $min: "$score" } } },
{ $sort: { _id: 1, score: 1 } },
]);
let stream = agg.stream(collection);
let result = agg.run(collection);
Options
Query and aggregation operations can be configured with options to enabled different features or customize how documents are processed. Some options are only relevant to specific operators and need not be specified if not required.
interface Options {
readonly idKey?: string;
readonly collation?: CollationSpec;
readonly processingMode?: ProcessingMode;
readonly useStrictMode?: boolean;
readonly scriptEnabled?: boolean;
readonly hashFunction?: HashFunction;
readonly collectionResolver?: CollectionResolver;
readonly jsonSchemaValidator?: JsonSchemaValidator;
}
Differences from MongoDB
- There is no concept of a collection. Input data is either an array of objects or a generator function to support streaming.
- Does not support server specific operators. E.g.
$collStat
, $planCacheStats
, $listSessions
. - Does not support GeoJSON query operators.
- Does not support query operators;
$comment
, $meta
, $text
. - Does not support aggregation expression operators;
$toObjectId
, $binarySize
, bsonSize
. - Agregation pipeline operator
$merge
enforces unique constraint on the lookup field at runtime. - Custom function evaluation operators;
$where
, $function
, and $accumulator
, do not accept strings as the function body. - Custom function evaluation operators are enabled by default. They can be disabled with the
scriptEnabled
option. - Custom function evaluation operator $accumulator does not support the
merge
option. - The
$jsonSchema
operator requires the user to register their own validator using the jsonSchemaValidator
option.
Benefits
- Better alternative to writing custom code for transforming collection of objects
- Quick validation of MongoDB queries without the need for a database
- MongoDB query language is among the best in the market and is well documented
Contributing
- Squash changes into one commit
- Run
npm test
to build and execute unit tests - Submit pull request
To validate correct behaviour and semantics of operators, you may also test against mongoplayground.net.
License
MIT