micromongo
v1.0.0
Published
Mongodb-like queries over standard arrays of objects
Downloads
427
Maintainers
Readme
micromongo
MongoDB-like queries over plain JavaScript arrays of objects — zero database, in-memory.
📖 Full documentation & live playground →
An array of objects (documents, in MongoDB's terms) is a very common data structure. If your app
works with this kind of data, you want something lightweight, and you already know MongoDB's query
syntax, micromongo lets you run the same find/update/aggregate you'd write against MongoDB —
directly over the array. It runs in Node and the browser, ships TypeScript types, and needs no
server.
var mm = require("micromongo");
var orders = [
{ status: "A", qty: 30 },
{ status: "B", qty: 10 },
{ status: "A", qty: 50 },
];
// Functional API — query/aggregate any array directly (linear scan):
mm.find(orders, { status: "A", qty: { $gte: 30 } });
// [ {status:'A',qty:30}, {status:'A',qty:50} ]
mm.aggregate(orders, [{ $group: { _id: "$status", total: { $sum: "$qty" } } }]);
// [ {_id:'A',total:80}, {_id:'B',total:10} ]For larger collections, wrap the data in a Collection and add an ordered index (single-field /
multikey / compound) to serve equality, range, sort, $in, compound-prefix and $or queries from the
index instead of scanning. The functional mm.find(array, …) API stays a scan by design (it can't own
the caller's array to keep an index valid); the Collection API is the path to scale.
// Collection API — chainable cursors + opt-in indexes (the scale path):
var c = new mm.Collection(orders);
c.createIndex({ status: 1 });
c.find({ status: "A" }).sort({ qty: -1 }).limit(1).toArray();
// [ {status:'A',qty:50} ] — served via IXSCANCursors also stream — for…of, for await, spread, or a Node .stream() — pulling one doc at a
time and stopping early on limit (so find(q).limit(5) over a huge array never scans the rest).
When a sort is combined with a limit, it uses a bounded top-K heap (O(K) memory — it never
materializes the full sorted array):
for (const order of c.find({ status: "A" }).limit(5)) {
/* … */
} // stops after 5
c.find({}).sort({ qty: -1 }).limit(10); // top-10 without buffering all NThe library is written in TypeScript and ships type definitions (.d.ts), so the read/write/
aggregate surface is typed against your document shape. require('micromongo') and the bin are
unchanged — it's still CommonJS, with ESM (import) and a browser IIFE build also provided.
Installation
npm install --save micromongovar mm = require("micromongo");Documentation
The full reference — every method, query/update operator, aggregation stage, the CLI, and a live in-browser playground — lives on the docs site:
📖 alykoshin.github.io/micromongo
Quick links:
- Reads —
countfindfindOnedistinct+ lazyCursor. - Writes & updates —
insert*deleteOne/deleteManyupdateOne/updateManyreplaceOnefindOneAnd*bulkWrite, with field, array, positional ($,$[],$[<id>]) and bitwise update operators, plusupsert. - Query operators — comparison,
logical, element, evaluation (
$regex/$where/$mod/$text/$expr), array, bitwise, geospatial. - Aggregation — every pipeline stage feasible in-memory + a pragmatic expression-operator core.
- Collections & indexes — opt-in ordered
indexes with a query planner and
explain(). - Streaming cursors —
for…of/for await/ Node.stream(), with early-termination onlimitand bounded top-K forsort+limit. - Extensibility — register custom query
operators via
mm.registerOperator. - CLI / REPL — a mongosh-flavored, in-memory shell.
- MongoDB driver mock —
micromongo/mock, a drop-inmongodb-driver-shaped adapter for testing (see below). - Performance — scan-vs-index benchmarks.
Runnable snippets are in the examples/ directory (node examples/index.js); the
experiments/ directory shows advanced use — extending the engine at runtime with
custom query/aggregate operators (registerOperator); and the tests in test/ double as
executable specs.
This is the documentation for the current 1.x release. The old pre-rewrite API (v0.3.x, no
indexes / no Collection, node >= 0.11) is archived at
docs/legacy-readme-0.3.1.md for reference.
Target node version: >= 12.
Compatibility
micromongo aims for MongoDB-compatible semantics (baseline: MongoDB 3.2 docs, plus selected newer
operators like $expr/$rand). The full, per-operator status matrix — every method, query/update
operator and aggregation stage, with per-operator notes — lives in two always-in-sync places:
- Compatibility on the docs site → (with a live ops table that runs the real engine in your browser), and
planning/compatibility.md— the generated Markdown table.
Both are verified by the *-mongodoc.js tests (ported verbatim from the MongoDB docs) and a differential
harness that replays the same examples against a real MongoDB server.
⚠️ Security —
$where:$whereexecutes arbitrary JavaScript against each document (in Node via thevmmodule — which is not a security sandbox — and in the browser vianew Function). Treat$whereas trusted-input-only: only pass it queries your own code builds, never a$whereexpression assembled from end-user input. For computed queries over untrusted input, prefer a value-based query or$expr(which runs no JS).
MongoDB driver mock (micromongo/mock)
micromongo/mock is a drop-in, mongodb-driver-shaped adapter backed by the in-memory engine — so
other projects can run their existing test suites against micromongo instead of a live MongoDB. It
mirrors the native driver (MongoClient / Db / Collection / cursors / ObjectId, async results,
for await), so you can point the code under test at it without touching that code — e.g. in Jest:
// jest.config.js
module.exports = { moduleNameMapper: { "^mongodb$": "micromongo/mock" } };See the mock adapter docs → for the full surface,
the bson ObjectId handling, and which server-only features are no-ops vs. throw.
Testing
npm run _test # build + run the suite (mocha + nyc), type tests, and bundle smokes
npm test # the above + lint/audit/deps checks, coverage report, and status badgesThere is no cloud CI; the tests and coverage badges above are generated locally from
the real numbers by scripts/gen-badges.js (run as part of npm test)
and committed under docs/badges/ — so they always reflect the last full run.
If you have different needs regarding the functionality, please add a feature request.
Credits
Links
github.com npmjs.com docs & playground
License
MIT
