0.1.0 • Published 7 years ago

mongoish v0.1.0

Weekly downloads
1
License
MIT
Repository
github
Last release
7 years ago

Mongoish

MongoDB-style persistence for multiple back-ends including Redis.

Testing

With Mongo:

$ MONGO_URL=mongodb://localhost/test npm test

With Redis:

$ REDIS_URL=redis://localhost/9 npm test

Error Factory

Oftentimes it's useful to be able to provide an error factory. For example, in a JSON-API based API service, it's useful for all modules within the service to pass a JsonApiErrors object that might be defined as:

module.exports = class JsonApiErrors extends Array {
  
  constructor(err) {
    super()
    
    if (_.isUndefined(err)) {
      ;
    } else if (err instanceof JsonApiErrors || _.get(err.constructor.name)==='JsonApiErrors') {
      _.map(err, (err_) => {
        this.push(_.clone(err_))
      })
    } else if (_.isString(err)) {
      this.push({status:500, detail:err})
    } else if (_.isNumber(err)) {
      this.push({status:err})
    } else if (_.isArray(err)) {
      _.map(err, (err_) => {
        this.push(err_)
      })
    } else if (_.isObject(err)) {
      if (!_.isNumber(err.status)) {err.status=500}
      this.push(err)
    }
  }
}

You can register an error factory for it as follows:

let mongoish = require('mongoish')

let url = 'redis://localhost/9'
let Adapter = mongoish.adapterFor(url)

let opts = {errorFactory:errorFactory}
let adapter = new Adapter(opts)

function errorFactory(err) {
  return new JsonApiErrors(err)
}

Indexes

Indexes are defined using the mongodb-sync-indexes Index List format.

The indexing system was primary designed so that secondary index lookups could be performed on Redis:

let query = {firstName:'Joe'}
let doc = adapter.findOne(query, cb)

Using:

let indexList = {
  "people":[
    {"name":"first_1", "key":{"first":1},
    {"name":"last_1", "key":{"last":1}
  ]
}
let url = 'redis://localhost/9'
let Adapter = mongoish.adapterFor(url)
let adapter = new Adapter({indexList:indexList})
async.waterfall([
  function(cb) {
    adapter.connect(url, cb)
  },
  function(connectResult, cb) {
    let doc = {id:123,first:'John',last:'Doe'}
    adapter.insertOne('people', doc, cb)
  },
  function(insertResult, cb) {
    let query = {first:'John'}
    adapter.findOne('people', query, cb)
  }
})

The insertOne command above produces the following Redis activity:

$ redis-cli
monitor
"multi"
"set" "person:123" "{\"first\":\"John\",\"last\":\"Doe\"}"
"sadd" "people:ids" "123"
"set" "people:first_1:John" "123"
"set" "people:first_1:John$type" "number"
"set" "people:last_1:Doe" "123"
"set" "people:last_1:Doe$type" "number"
"exec"

The findOne command above produces the following Redis activity:

"multi"
"get" "people:first_1:John"
"get" "people:first_1:John$type"
"exec"
"get" "person:123"