MongoDB Driver with simple and compact API, it also eliminates some callbacks.

Install it with `npm install mongo-lite`, examples are in `/examples` folder.

The project hosted on GitHub You can report bugs and discuss features on the Issues page.


Database

connect `connect(url, [names])`
Connect to MongoDB, optionally takes list of collection names.
Url should be in form of `"mongodb://[username:password@]host[:port]/dbname"`

var db = require('mongo-lite').connect('mongodb://localhost/test', ['posts', 'comments'])
db.posts.insert({title: 'first'}, function(err, doc){})

collection `collection(name, [options])`
Get collection.

db.collection('posts').insert({title: 'first'}, function(err, doc){})

db.posts = db.collection('posts')
db.posts.insert({title: 'first'}, function(err, doc){})

clear `clear(callback)`
Clears database, useful in testing.

db.clear(function(err){})

CRUD

insert `insert(doc, [options], callback)`
Insert document into database, if document's `_id` not defined it will be set automatically. You can also use `create` instead of `insert`.

db.posts.insert({title: 'first'}, function(err, doc){})

update `update(selector, doc, [options], callback)`
Updates or replaces document or documents selected by selector.

db.posts.insert({title: 'first'}, function(err, doc){
  doc.title = 'second'
  db.posts.update({_id: doc._id}, doc, function(err){})
})

save `save(doc, [options], callback)`
Save document, if document not exist it will be inserted into database using `insert`, if it already exist it will be updated using `update`, so basically it's just a shortcut for `insert` and `update` methods.

db.posts.save({title: 'first'}, function(err, doc){
  doc.title = 'second'
  db.posts.save(doc, function(err, doc){})
})

remove `remove(selector, [options], callback)`
Removes document or documents selected by selector. You can also use `delete` instead of `remove`.

db.posts.insert({title: 'first'}, function(err, doc){
  db.posts.remove({_id: doc._id}, function(err){})
})

Querying

first `first([selector, [options]], callback)`
Get first document specified by selector and options, can be used with chainable query helpers.

db.posts.first(function(err, doc){})
db.posts.first({published: true}, {sort: {title: 1}}, function(err, doc){})
db.posts.find({published: true}).sort({title: 1}).first(function(err, doc){})
db.posts.sort({title: 1}).first({published: true}, function(err, doc){})

all `all([selector, [options]], callback)`
Get list of documents specified by selector and options, can be used with chainable query helpers.

db.posts.all(function(err, docs){})
db.posts.all({published: true}, {sort: {title: 1}, limit: 10}, function(err, docs){})
db.posts.find({published: true}).sort({title: 1}).limit(10).all(function(err, docs){})
db.posts.sort({title: 1}).limit(10).all({published: true}, function(err, docs){})

count `count([selector, [options]], callback)`
Get count of documents specified by selector, can be used with chainable query helpers.

db.posts.count(function(err, count){})
db.posts.count({published: true}, function(err, count){})
db.posts.find({published: true}).count(function(err, count){})

remove `remove([selector, [options]], callback)`
Remove documents selected by selector, can be used with chainable query helpers.

db.posts.remove({published: true}, function(err){})
db.posts.find({published: true}).remove(function(err){})

next `next(callback)`
Low-level method to iterate over collection using cursor, can be used with chainable query helpers. Usually You use `first` and `all` methods, and use `next` only in specific cases.
Every call to `next` returns object from collection, if there's no more element `null` will be returned.
Cursor will be closed automatically when You get the last element, but if You stop iterating before getting the last element You should close it explicitly by calling `cursor.close()`.

var cursor = db.posts.find()
var cursor = db.posts.find({published: true}, {sort: {title: 1}, limit: 10})
var cursor = db.posts.find({published: true}).sort({title: 1}).limit(10)

var printNext = function(){
  cursor.next(function(err, doc){
    if (doc) {
      console.log(doc)
      printNext()
    }
  })
}
printNext()

Query Helpers

You can build query directly using `selector` and `options`, but sometimes it's handy to have chainable query builders like `limit`, `sort`, `skip`. They can be combined in any order.

sort `sort(fields)`
Add sorting to query.

db.posts.sort({createdAt: -1, title: 1}).all(function(err, docs){})

limit `limit(n)`
Limit queried documents.

db.posts.limit(10).all(function(err, docs){})

skip `skip(n)`
Skip documents.

db.posts.skip(10).all(function(err, docs){})

paginate `paginate(page, perPage)`
Paginate returning documents, just a handy shortcut, uses `skip` and `limit` internally.

db.posts.paginate(2, 10).all(function(err, docs){})

snapshot `snapshot()`
Enables snapshot mode for query.

db.posts.snapshot().all(function(err, docs){})

Compatibility with underlying native MongoDB Driver

All methods of native driver also available, use it in the same way. For example - You can call `ensureIndex` on collection as usual.

db.posts.ensureIndex({createdAt: -1}, function(err){})

Defaults & Setting

By default MongoDB tuned for top performance, for services like logging & analytics, non-critical for data loss and errors.

But, for services like blogs, sites, e-commerce and so on You usually want different defaults. You can change it globally if You need.

var mongo = require('mongo-lite')

// Make all queries safe by default.
mongo.options.safe = true

// Make update to update all matched documents by default, not just the first one.
mongo.options.multi = true

// Use short string ids like `a1jaK` instead of `ObjectId("47cc67093475061e3d95369d")`.
mongo.extendedOptions.generateId = true

// Use `id` instead of `_id`.
mongo.extendedOptions.convertId = true

// There's also a method that does all this.
mongo.useHandyButNotStandardDefaults()

// You can disable logging with this.
db.log = null

Synchronous mode

There's an extension to driver that wraps its API and allows to use it as if it's synchronous (without blocking Node.js, by using fibers).

Below are sample code showing how it looks like.

require('mongo-lite/lib/synchronize')
...
var doc = db.posts.insert({title: 'first', published: false})
doc.text = 'bla bla ...'
db.posts.update({_id: doc._id}, doc)
db.posts.remove({_id: doc._id})
...

Notice - there's no callbacks, for more details look at `/examples/exampleSync.js`, or read more about it synchronize.js.

Usage with mocha.js

Use `clear` to clear database before each test.

describe('Posts', function(){
  beforeEach(function(next){
    this.db = mongo.connect('mongodb://localhost/test')
    this.db.clear(next)
  })

  it('should be empty', function(next){
    this.db.collection('posts').count(function(err, count){
      if(err) return next(err)
      expect(count).to.eql(0)
      next()
    })
  })
})

Copyright Alexey Petrushin, released under MIT License