jluchiji/mongo-stash

View on GitHub
README.md

Summary

Maintainability
Test Coverage
# MongoStash

[![Circle CI][ci-badge]][ci-link]
[![Code Climate][cc-badge]][cc-link]
[![Test Coverage][cov-badge]][cov-link]

MongoStash is a thin wrapper around [mongodb][native-link] collections that
provides transparent caching by ID via [lru-cache][lru-link].

MongoStash is designed for use cases where the vast majority of database
operations revolve around manipulating single records by their IDs. Meanwhile,
MongoStash preserves the ability to update/delete multiple records while keeping
the cache integrity.

# Getting Started
```sh
$ npm install mongo-stash --save
```

# Documentation

## Core

###`MongoStash(collection[, options])`

Creates a new MongoStash instance wrapping the `collection`. You can optionally
specify caching parameters using the `options` arguments, which is directly
passed to the underlying LRU cache.

```js
const MongoDB    = require('mongodb');
const MongoStash = require('mongo-stash');

/* You need a native mongodb connection first */
const db = yield MongoDB.connect('mongodb://localhost:27017/test');

/* Then, create the MongoStash wrapper */
const stash = MongoStash(db.collection('foo'), { max: 1000, maxAge: 60 });
 ```

### `defaults`
An object of a function specifying default properties and their values for every
inserted document (e.g. timestamp).

If it is an object, it will be merged into new document before insertion.

If it is a function, it will be called with the new document as the only argument,
then the result will be merged into the new document.

```js
const stash = MongoStash(collection);
stash.defaults = (doc) => ({ timestamp: new Date() });

const result = yield stash.insertOne({ foo: 'bar' });
/* result: { _id: ObjectID(...), foo: 'bar', timestamp: Date(...) } */
```

### `projection`
Default projection for uncached find operations.
```js
const stash = MongoStash(collection);
stash.projection = { fields: { index: false } };

yield stash.insertOne({ foo: 'bar', index: 1 });
const result = yield stash.find();
/* result: [{ _id: ObjectID(...), foo: 'bar' }] */
```

### `safeMode`
If set to `true` forces all update/delete operations on multiple documents to
wipe entire cache. Usually not needed.
```js
const stash = MongoStash(collection);
stash.safeMode = true;

yield stash.deleteMany({ foo: 'bar' });
/* Cache is reset at this point */
```

## Find

### `findById(id)`
Finds a document by its ID, retrieving it from cache if possible. The `id` can
be either a string or a BSON ObjectID.

```js
const stash = MongoStash(collection);

/* Queries the database, since the ObjectID is not cached */
const document = yield stash.findById('5625eb34622fcb9b5937677f');

/* Does not query the database, retrieves from cache instead */
const another = yield stash.findById('5625eb34622fcb9b5937677f');
```

### `find(query, proj)`
Equivalent to the native `Collection.find()` method. MongoStash cannot cache by
query, therefore this method cannot utilize caching capabilities.

```js
const stash = MongoStash(collection);

const results = yield stash.find({ index: { $gt: 100 } });
```

### `findOne(query, proj)`
Equivalent to the native `Collection.findOne()` method. MongoStash cannot cache by
query, therefore this method cannot utilize caching capabilities.

**NOTE:** If you need to find a document by its ID, consider using `findById()`
instead to utilize caching.

```js
const stash = MongoStash(collection);

const result = yield stash.findOne({ index: 3 });
```

## Insert
### `insertOne(doc [, options])`
Inserts one document into the collection, also caching it. You can optionally
specify `options`, which are passed to the native `insertOne()` method.

Before inserting, the `doc` is merged with the `MongoStash.defaults`. The
`doc` is not modified during the merging process.

```js
const stash = MongoStash(collection);

const result = yield stash.insertOne({ index: 3 });
```

### `insertMany(docs [, options])`
Inserts multiple documents into the collection, also caching them. You can optionally
specify `options`, which are passed to the native `insertMany()` method.

Before inserting, each of `docs` is merged with the `MongoStash.defaults`.
The `docs` are not modified during the merging process.

```js
const stash = MongoStash(collection);

const result = yield stash.insertMany([{ index: 3 }, { index: 4 }]);
```

## Update
### `updateOne(id, changes[, options])`
Updates a single document by its ID, also caching the change. You can optionally
specify `options`, which are passed to the native `findOneAndUpdate()` method.

```js
const stash = MongoStash(collection);

const id = '5625eb34622fcb9b5937677f';
const result = yield stash.updateOne(id, { $set: { index: 9 } });
```

### `updateMany(query, changes[, options])`
Updates multiple documents, dropping matched documents from cache. You can optionally
specify `options`, which are passed to the native `updateMany()` method.

**NOTE:** This method is executed using two queries by first looking up matching
IDs, then performing the update on them. Any documents inserted **after** the initial
lookup will not be updated. If you need to prevent this, consider using `updateSafe()`
or setting `MongoStash.safeMode` to true.

```js
const stash = MongoStash(collection);

const result = yield stash.updateMany({ index: { $lt: 20 } }, { $set: { index: 9 } });
```

### `updateSafe(query, changes[, options])`
Updates multiple documents in one query, dropping **all** of the cache. You can optionally
specify `options`, which are passed to the native `updateMany()` method.

If `MongoStash.safeMode` is true, all calls to `updateMany()` will be redirected here.

```js
const stash = MongoStash(collection);

const result = yield stash.updateSafe({ index: { $lt: 20 } }, { $set: { index: 9 } });
```

## Delete
### `deleteOne(id)`
Deletes a single document by its ID, dropping it from the cache.

```js
const stash = MongoStash(collection);

const id = '5625eb34622fcb9b5937677f';
const result = yield stash.deleteOne(id);
```

### `deleteMany(query)`
Deletes multiple documents, dropping them from cache.

**NOTE:** This method is executed using two queries by first looking up matching
IDs, then performing the delete on them. Any documents inserted **after** the initial
lookup will not be deleted. If you need to prevent this, consider using `deleteSafe()`
or setting `MongoStash.safeMode` to true.

```js
const stash = MongoStash(collection);

const result = yield stash.deleteMany({ index: { $lt: 20 } });
```

### `deleteSafe(query)`
Deletes multiple documents in one query, dropping **all** of the cache.

If `MongoStash.safeMode` is true, all calls to `deleteMany()` will be redirected here.

```js
const stash = MongoStash(collection);

const result = yield stash.deleteSafe({ index: { $lt: 20 } });
```


[ci-badge]: https://circleci.com/gh/jluchiji/mongo-stash.svg?style=svg
[ci-link]:  https://circleci.com/gh/jluchiji/mongo-stash

[cc-badge]: https://codeclimate.com/github/jluchiji/mongo-stash/badges/gpa.svg
[cc-link]: https://codeclimate.com/github/jluchiji/mongo-stash

[cov-badge]: https://codeclimate.com/github/jluchiji/mongo-stash/badges/coverage.svg
[cov-link]: https://codeclimate.com/github/jluchiji/mongo-stash/coverage

[native-link]: https://github.com/mongodb/node-mongodb-native
[lru-link]: https://github.com/isaacs/node-lru-cache