<commit_before>[![npm version](https://badge.fury.io/js/micromongo.svg)](http://badge.fury.io/js/micromongo)
[![Build Status](https://travis-ci.org/alykoshin/micromongo.svg)](https://travis-ci.org/alykoshin/micromongo)
[![Coverage Status](https://coveralls.io/repos/alykoshin/micromongo/badge.svg?branch=master&service=github)](https://coveralls.io/github/alykoshin/micromongo?branch=master)
[![Code Climate](https://codeclimate.com/github/alykoshin/micromongo/badges/gpa.svg)](https://codeclimate.com/github/alykoshin/micromongo)
[![Inch CI](https://inch-ci.org/github/alykoshin/micromongo.svg?branch=master)](https://inch-ci.org/github/alykoshin/micromongo)

[![Dependency Status](https://david-dm.org/alykoshin/micromongo/status.svg)](https://david-dm.org/alykoshin/micromongo#info=dependencies)
[![devDependency Status](https://david-dm.org/alykoshin/micromongo/dev-status.svg)](https://david-dm.org/alykoshin/micromongo#info=devDependencies)


# micromongo

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](#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()`](#count), 
- [`find()`](#find),
- [`findOne()`](#findone)
- [`deleteOne()`](#deleteone)
- [`deleteMany()`](#deletemany)
- [`remove()`](#remove)
- [`insert()`](#insert)
- [`insertOne()`](#insertone)
- [`insertMany()`](#insertmany)
- [`aggregate()`](#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](#compatibility-matrix) below.

Tests contains over 150 different test cases based on module's logic and examples from Mongodb docs.


## Installation

```sh
npm install --save micromongo
```


# Usage

## `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');
res = mm.find(array, query, projection);

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.

```<commit_msg>minor readme fix<commit_after>[![npm version](https://badge.fury.io/js/micromongo.svg)](http://badge.fury.io/js/micromongo)
[![Build Status](https://travis-ci.org/alykoshin/micromongo.svg)](https://travis-ci.org/alykoshin/micromongo)
[![Coverage Status](https://coveralls.io/repos/alykoshin/micromongo/badge.svg?branch=master&service=github)](https://coveralls.io/github/alykoshin/micromongo?branch=master)
[![Code Climate](https://codeclimate.com/github/alykoshin/micromongo/badges/gpa.svg)](https://codeclimate.com/github/alykoshin/micromongo)
[![Inch CI](https://inch-ci.org/github/alykoshin/micromongo.svg?branch=master)](https://inch-ci.org/github/alykoshin/micromongo)

[![Dependency Status](https://david-dm.org/alykoshin/micromongo/status.svg)](https://david-dm.org/alykoshin/micromongo#info=dependencies)
[![devDependency Status](https://david-dm.org/alykoshin/micromongo/dev-status.svg)](https://david-dm.org/alykoshin/micromongo#info=devDependencies)


# micromongo

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](#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()`](#count), 
- [`find()`](#find),
- [`findOne()`](#findone)
- [`deleteOne()`](#deleteone)
- [`deleteMany()`](#deletemany)
- [`remove()`](#remove)
- [`insert()`](#insert)
- [`insertOne()`](#insertone)
- [`insertMany()`](#insertmany)
- [`aggregate()`](#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](#compatibility-matrix) below.

Tests contains over 150 different test cases based on module's logic and examples from Mongodb docs.


## Installation

```sh
npm install --save micromongo
```


# Usage

## `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.

```
{'fraction_non_alphanumeric': 0.15719930847122746, 'fraction_numerical': 0.0079031859718449, 'mean_word_length': 4.864590876176684, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 26, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1101965', 'n_tokens_mistral': 2722, 'n_tokens_neox': 2440, 'n_words': 810}