
Research
Supply Chain Attack on Axios Pulls Malicious Dependency from npm
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.
micromongo
Advanced tools
Mongodb-like queries over standard arrays of objects.
Array of objects (documents in Mongodb's terminology) is a very common data structure in programming. If your application widely using this type of data, if you are looking for something relatively lightweight and you are familiar with Mongodb syntax, you may consider this package to handle the arrays of objects.
Please, be aware that this module is working on unsorted arrays and does not uses indexes, so it is not intended to be used with relatively big arrays (thousands of elements) and not purposed for that tasks (see performance section).
If you have big sets of data, I'd recommend to consider minimongo's Collection or Mongodb itself.
Currently following methods are supported:
count(),find(),findOne()deleteOne()deleteMany()remove()insert()insertOne()insertMany()aggregate() (stages skip, limit, sort, unwind, partially project)Not supported: indexes, geolocation, bitwise operators etc; also not supported cursor methods skip(), limit(), sort().
Limited support for querying array elements; not supported /pattern/ syntax (without $regexp)
For more info see compatibility matrix below.
Tests contains over 200 different test cases based on module's logic and examples from Mongodb docs.
Supported node version >= 0.11.
npm install --save micromongo
count()Method count() return number of documents matching query.
Syntax:
res = mm.count(array, query);
array - array of objects
query - query object
Following example returns number of elements with a >= 2 (i.e. 2):
var mm = require('micromongo');
res = mm.count([ { a: 1 }, { a: 2 }, { a: 3 }, ], { a: { $gte: 2 } });
// res = 2
If query is undefined or empty object ({}), method returns total count of elements in array:
var mm = require('micromongo');
res = mm.count([ { a: 1 }, { a: 2 }, { a: 3 }, ], {});
// res = 3
find()Method find() returns deep copy (with some type limitations) of array's documents matching query with fields matching projection.
If documents in array contains _id field, projection follows standard Mongo agreement to include it in output document by default.
var mm = require('micromongo');
inventory = [
{ qty: 10, carrier: { fee: 3 }, price: 3 },
{ qty: 20, carrier: { fee: 2 }, price: 2 },
{ qty: 30, carrier: { fee: 1 }, price: 1 },
];
var query = { qty: { $gt: 20 } };
var res = mm.find(inventory, query);
// { qty: 30, carrier: { fee: 1 }, price: 1 },
findOne()Method findOne() returns deep copy (with some type limitations) of first array's documents matching query with fields matching projection.
If documents in array contains _id field, projection follows standard Mongo agreement to include it in output document by default.
doc = mm.findOne(array, query, projection);
deleteOne()Method deleteOne() removes from array its first document matching query.
Returns document containing
deletedCount containing the number of deleted documentsvar res = mm.deleteOne(array, query);
// { deletedCount: 1 }
deleteMany()Method deleteMany() removes from array all its documents matching query.
var res = mm.deleteMany(array, query);
// { deletedCount: 1 }
Returns document containing
deletedCount containing the number of deleted documentsremove()Method remove() removes from array its first document matching query or all documents matching query.
var res = mm.remove(array, query);
// { nRemoved: 1 }
var res = mm.remove(array, query, {});
// { nRemoved: 1 }
Parameters:
options] - may be boolean or document containing boolean property justOne. Optional, default: false. Determines, all matched documents to be removed or only first of them.Returns document containing
nRemoved containing the number of deleted documentsParameters:
options] - may be boolean or document containing boolean property justOne. Optional, default: false. Determines, all matched documents to be removed or only first of them.Returns document containing
nRemoved containing the number of deleted documentsinsert()While Mongo creates new Collection if it does not exists, for micromongo array must exists.
var res = mm.insert(array, sourceDocOrArray, options);
// { nInserted: 1 }
options.ordered - boolean - not supportedinsertOne()While Mongo creates new Collection if it does not exists, for micromongo array must exists.
var res = mm.insertOne(array, sourceDoc, options);
// { nInserted: 1 }
insertMany()While Mongo creates new Collection if it does not exists, for micromongo array must exists.
var res = mm.insert(array, sourceArray, options);
// { nInserted: 1 }
options.ordered - boolean - not supportedaggregate()var res = mm.aggregate(array, stages);
stages - array of aggregation pipeline stages.
Currently supported aggregation pipeline stages:
$limit - mm.aggregate([ { $limit: 5 } ])
$skip - mm.aggregate([ { $skip: 5 } ])
$sort - mm.aggregate([ { $sort: { a: 1 }, { 'a.b': -1 } } ])
Array and objects in $sort not currently supported.
$unwind - mm.aggregate([ { $unwind: '$customer.items' } ]) ormm.aggregate([ { $unwind: {
path: '$customer.items',
includeArrayIndex: 'idx',
preserveNullAndEmptyArrays: true
}
])`
//var mm = require('../');
var mm = require('micromongo');
var array, query, res;
array = [
{ a: 1 },
{ a: 2 },
{ a: 3 },
];
query = { a: { $gte: 2 } };
res = mm.count(array, query);
console.log(res);
// 2
query = {};
res = mm.count(array, query);
console.log(res);
// 3
//var mm = require('../');
var mm = require('micromongo');
var array, query, projection, res;
array = [
{ qty: 10, price: 10 },
{ qty: 10, price: 0 },
{ qty: 20, price: 10 },
{ qty: 20, price: 0 },
{ qty: 30, price: 10 },
{ qty: 30, price: 0 },
];
query = { $or: [ { quantity: { $eq: 20 } }, { price: { $lt: 10 } } ] };
projection = { qty: 1 };
res = mm.find(array, query, projection);
console.log(res);
// [ { qty: 10 }, { qty: 20 }, { qty: 30 } ]
You can find these examples in examples/ subdirectory.
To run all the examples at once you may start node examples\index.js.
For more examples please also have a look on tests in tests/ subdirectory.
If you have different needs regarding the functionality, please add a feature request.
For unit tests run:
npm run _test
As it was mentioned, micromongo runs on unsorted unindexed data, so it can't show good performance on big arrays.
Test system:
Tests showed following results for operations count, find, aggregate $sort over arrays of 1000, 10000, 100000 elements:
#performance
Processed 1000 elements - Elapsed: 26 ms
✓ # count 1000 elements
Processed 10000 elements - Elapsed: 261 ms
✓ #count 10000 elements (262ms)
- # count 100000 elements
Processed 1000 elements - Elapsed: 26 ms
✓ # find 1000 elements
Processed 10000 elements - Elapsed: 246 ms
✓ # find 10000 elements (247ms)
- # find 100000 elements
Processed 1000 elements - Elapsed: 15 ms
✓ # sort 1000 elements
Processed 10000 elements - Elapsed: 102 ms
✓ # sort 10000 elements (102ms)
- # sort 100000 elements
Processed 1000 elements - Elapsed: 481 ms
✓ # node version >= v5.3.0 - find $where 1000 elements (481ms)
Processed 5000 elements - Elapsed: 2997 ms
✓ # node version >= v5.3.0 - find $where 5000 elements (2997ms)
For node version < 5.3.0 $where is significantly slower due to imementation of vm.
You may have a look on the data used for the tests in tests/performance.js, and running tests by yourself by npm run _test and checking the console log for performance output.
At the moment supports only find() and findOne() operations.
If documents in array contains _id field, projection follows standard Mongo agreement to include it in output document by default.
Matrix below is based on Mongodb 3.2 documentation.
Method | Status | ------------------------|--------|-------------------------- aggregate() | + | see Aggregation Pipeline Operators bulkWrite() | ? | count() | + | copyTo() | + | createIndex() | NA | dataSize() | NA | deleteOne() | + | deleteMany() | + | distinct() | ? | drop() | NA | dropIndex() | NA | dropIndexes() | NA | ensureIndex() | NA | explain() | NA | find() | + | findAndModify() | ? | findOne() | + | findOneAndDelete() | ? | findOneAndReplace() | ? | findOneAndUpdate() | ? | getIndexes() | NA | getShardDistribution() | NA | getShardVersion() | NA | group() | ? | insert() | + | insertOne() | + | insertMany() | + | isCapped() | NA | mapReduce() | ? | reIndex() | NA | replaceOne() | ? | remove() | + | renameCollection() | NA | save() | NA | stats() | NA | storageSize() | NA | totalSize() | NA | totalIndexSize() | NA | update() | . | updateOne() | . | updateMany() | . | validate() | NA |
NA - Not Applicable
? - Not planned
. - Not implemented
| Operator | Status | Comment |
|---|---|---|
| $eq | + | |
| $ne | + | |
| $gt | + | |
| $gte | + | |
| $lt | + | |
| $lte | + | |
| $in | + | |
| $nin | + | arrays not supported |
| Operator | Status |
|---|---|
| $and | + |
| $or | + |
| $not | + |
| $nor | + |
| Operator | Status |
|---|---|
| $exists | + |
| $type | + |
| Operator | Status | Comment |
|---|---|---|
| $mod | + | |
| $regex | + | Not supported o, x options |
| $text | ? | |
| $where | + | Timeout hardcoded to 1000 ms |
| Operator | Status |
|---|---|
| $geoWithin | ? |
| $geoIntersects | ? |
| $near | ? |
| $nearSphere | ? |
| $geometry | ? |
| $minDistance | ? |
| $maxDistance | ? |
| $center | ? |
| $centerSphere: | ? |
| $box | ? |
| $polygon | ? |
| $uniqueDocs | ? |
| Operator | Status | Comment |
|---|---|---|
| $all | + | Not supported: (1) nested arrays, (2) use with $elemMatch, |
| $elemMatch | + | |
| $size | + |
| Operator | Status |
|---|---|
| $bitsAllSet | ? |
| $bitsAnySet | ? |
| $bitsAllClear | ? |
| $bitsAnyClear | ? |
| Operator | Status | Comment |
|---|---|---|
| $comment | + | Logs to console |
| Operator | Status |
|---|---|
| $ | . |
| $all | . |
| $elemMatch | . |
| $size | . |
$inc $mul $rename $setOnInsert $set $unset $min $max $currentDate
$ $addToSet $pop $pullAll $pull $pushAll $push
$each $slice $sort $position
$bit
$isolated
| Operator | Status |
|---|---|
| $project | + |
| $match | + |
| $redact | . |
| $limit | + |
| $skip | + |
| $unwind | + s |
| $group | . |
| $sample | . |
| $sort | + |
| $geoNear | . |
| $lookup | . |
| $out | . |
| $indexStats | NA |
github.com npmjs.com travis-ci.org coveralls.io inch-ci.org
MIT
FAQs
Mongodb-like queries over standard arrays of objects
We found that micromongo demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.

Research
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.

Security News
TeamPCP is partnering with ransomware group Vect to turn open source supply chain attacks on tools like Trivy and LiteLLM into large-scale ransomware operations.