Mingo

MongoDB query language for in-memory objects

README

mingo


MongoDB query language for in-memory objects

Install


$ npm install mingo

Features


- Supports dot notation for both _`.`_ and _`.`_ selectors.
- Query and Projection Operators.

For documentation on using operators see mongodb

Browse package docs for modules.

Usage


  1. ```js
  2. // Use as es6 module
  3. import mingo from "mingo";

  4. // or vanilla nodeJS
  5. const mingo = require("mingo");
  6. ```

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 modulemingo/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.

  1. ```js
  2. // Note that doing this effectively imports the entire library into your bundle and unused operators cannot be tree shaked
  3. import "mingo/init/system";
  4. ```

Or from the node CLI

  1. ```sh
  2. node -r 'mingo/init/system' myscript.js
  3. ```

To support tree-shaking for client side bundles, you can import and register specific operators that will be used in your application.

ES6


  1. ```js
  2. import { useOperators, OperatorType } from "mingo/core";
  3. import { $trunc } from "mingo/operators/expression";
  4. import { $bucket } from "mingo/operators/pipeline";

  5. useOperators(OperatorType.EXPRESSION, { $trunc });
  6. useOperators(OperatorType.PIPELINE, { $bucket });
  7. ```

CommonJS


  1. ```js
  2. const core = require("mingo/core");
  3. const $trunc = require("mingo/operators/expression").$trunc;
  4. const $bucket = require("mingo/operators/pipeline").$bucket;
  5. const useOperators = core.useOperators;
  6. const OperatorType = core.OperatorType;

  7. useOperators(OperatorType.EXPRESSION, { $trunc: $trunc });
  8. useOperators(OperatorType.PIPELINE, { $bucket: $bucket });
  9. ```

Using query to test objects


  1. ```js
  2. import { Query } from "mingo";

  3. // create a query with criteria
  4. // find all grades for homework with score >= 50
  5. let query = new Query({
  6.   type: "homework",
  7.   score: { $gte: 50 }
  8. });

  9. // test if an object matches query
  10. query.test(doc);
  11. ```

Searching and Filtering


  1. ```js
  2. import { Query } from "mingo";

  3. // input is either an Array or any iterable source (i.e Object{next:Function}) including ES6 generators.
  4. let criteria = { score: { $gt: 10 } };

  5. let query = new Query(criteria);

  6. // filter collection with find()
  7. let cursor = query.find(collection);

  8. // alternatively use shorthand
  9. // cursor = mingo.find(collection, criteria)

  10. // sort, skip and limit by chaining
  11. cursor.sort({ student_id: 1, score: -1 }).skip(100).limit(100);

  12. // count matches. exhausts cursor
  13. cursor.count();

  14. // classic cursor iterator (old school)
  15. while (cursor.hasNext()) {
  16.   console.log(cursor.next());
  17. }

  18. // ES6 iterators (new cool)
  19. for (let value of cursor) {
  20.   console.log(value);
  21. }

  22. // all() to retrieve matched objects. exhausts cursor
  23. cursor.all();
  24. ```

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.

  1. ```js
  2. import { RawObject } from "mingo/types"
  3. import { JsonSchemaValidator } from "mingo/core"
  4. import Ajv, { Schema } from "ajv"

  5. const jsonSchemaValidator: JsonSchemaValidator = (s: RawObject) => {
  6.   const ajv = new Ajv();
  7.   const v = ajv.compile(s as Schema);
  8.   return (o: RawObject) => (v(o) ? true : false);
  9. };

  10. const schema = {
  11.   type: "object",
  12.   required: ["item", "qty", "instock"],
  13.   properties: {
  14.     item: { type: "string" },
  15.     qty: { type: "integer" },
  16.     size: {
  17.       type: "object",
  18.       required: ["uom"],
  19.       properties: {
  20.         uom: { type: "string" },
  21.         h: { type: "number" },
  22.         w: { type: "number" },
  23.       },
  24.     },
  25.     instock: { type: "boolean" },
  26.   },
  27. };

  28. // queries documents using schema validation
  29. find(docs, { $jsonSchema: schema }, {}, { jsonSchemaValidator }).all();
  30. ```

Note: An error is thrown when the $jsonSchema operator is used without a the jsonSchemaValidator configured.

Aggregation Pipeline


  1. ```js
  2. import { Aggregator } from "mingo/aggregator";
  3. import { useOperators, OperatorType } from "mingo/core";
  4. import { $match, $group } from "mingo/operators/pipeline";
  5. import { $min } from "mingo/operators/accumulator";

  6. // ensure the required operators are preloaded prior to using them.
  7. useOperators(OperatorType.PIPELINE, { $match, $group });
  8. useOperators(OperatorType.ACCUMULATOR, { $min });

  9. let agg = new Aggregator([
  10.   { $match: { type: "homework" } },
  11.   { $group: { _id: "$student_id", score: { $min: "$score" } } },
  12.   { $sort: { _id: 1, score: 1 } }
  13. ]);

  14. // return an iterator for streaming results
  15. let stream = agg.stream(collection);

  16. // return all results. same as `stream.all()`
  17. let result = agg.run(collection);
  18. ```