Norm.
The no-ORM for the most popular no-SQL database. Operates on vanilla JS objects, not complex models. Use the same Mongo methods you're used to from the shell, but with additional safeguards and helpers. Validate data against JSON schemas, rename fields, convert between ObjectIds and strings, handle standardized errors, and more.
Usage
Can run commands with make
or npm run
.
npm run prepublish
: Compiles Coffeescript to Javascript, once.npm run watch
: Runs build after every change.npm run test
: Runs tests.
Api
Initialization
Basic setup
var MongoClient = require('mongodb')
var Norm = require("norm");
MongoClient.connect("CONNECTION STRING", function(err, db) {
collection = db.collection("COLLECTION_NAME")
var schema = {
field1: {
type: "string",
required: true
}
};
var options = {};
var norm = new Norm(collection, schema, options);
});
Schema
- Follows standard (JSON Schema format)[http://json-schema.org/].
- Can include optional "rename" fields to store data with different names in mongo.
- Uses is-my-json-valid for conversion (at release, the fastest JSON schema validator for node)
Options
name
: Used in all error messages. (Default: The name of the collection)additionalProperties
: Whether to allow properties not in the schema. (Default: false)shardOn
: Name of the key to use as a source for the shard key. This should be a key of an Object Id value.shardKeyName
: If shardOn
is enabled, the name of the shard key. (Default: "k")shardRotation
: If shardOn
is enabled, the number of characters to rotate the shard key, for even distribution across shards. (Default: 2)validateIndexes
: If true, return an Index
error whenever a query would perform a full table scan.standardOptions
: Override default options for mongo queries. (Default: {j: true, w: 1, getLastError: 1, safe: true, multi: false, new: true}
)validatorOptions
: Override default options for is-my-json-valid. (Default: {verbose: true}
)
Queries
For all methods, the following holds.
-
If query argument is a string, then query will be set to {_id: ObjectId(query)}
- An
ObjectId
error will be returned if the id is invalid.
-
If the query argument is an array, then the query will be set to {_id: {$in: query.map(ObjectId)}}
- An
ObjectId
error will be returned if one or more id of the provided ids are invalid. - An
Empty
will be returned if the array has no elements. - If the array contains only one element, the query will instead be set to
{_id: ObjectId(query)}
-
In all other cases, the query is treated as a regular mongo query.
- Returns an
Operator
error if an unsupported operator is used.
-
Pass a callback to use callback-style. Don't pass a callback, and Norm will return you a Promise. The exception to this is findStream
, which always returns a streams.
Reads
norm.find(query[, options][, cb])
norm.findStream(query[, options])
- Same as
find
but returns a stream of results.
norm.findOne(query[, options][, cb])
- Returns a
NotFound
error if no document matches query
norm.count(query[, options][, cb])
Writes
norm.create(payload[, options][, cb])
- Returns an
Empty
error if payload is empty. - Returns a
Schema
error if schema is violated. - Returns a
Duplicate
error if uniqueness is violated.
norm.update(query, operation[, options][, cb])
- If operation does not contain any root-level update operators (
$set
, $merge
, etc), it will be wrapped with $set
. {multi: true}
must be passed to update multiple documents at once.- Returns an
Operator
error if an unsupported operator is used. - Returns an
Empty
error if any part of the operation payload is empty. - Returns a
Schema
error if schema is violated. - Returns a
Duplicate
error if uniqueness is violated. - DOES NOT return results. Use
findAndModify
for that, which is somewhat slower.
norm.findAndModify(query, operation[, options][, cb])
- Similar to
.update
, but returns the result - If "multi" option is set, returns an array of results. Otherwise returns a single result.
norm.remove(query[, options][, cb])
- If query argument is a string, then query will be set to {_id: ObjectId(query)}
Decorators
norm.decorate(methods, wrapper)
methods
is an array of strings, each of which should be a Norm method- For convenience,
Norm.READS
and Norm.WRITES
are included on the prototype. Norm.OPERATIONS
is their concatenation. - The wrapper function should be of the signature (methodName, args, operation, cb), where:
methodName
is the name of the wrapped methodargs
is an array of non-cb arguments passed to the methodoperation
will perform the requested operationcb
is the final callback. Remember to pass it the error and results!- The context is set to the norm.
For example, the following code will log all db operations:
norm.decorate(Norm.OPERATIONS, function(methodName, args, operation, cb) {
var start = Date.now();
var that = this;
operation(function(err, result) {
console.log("Collection:", that.name)
console.log("Executed:", methodName);
console.log("Arguments:", args);
console.log("Errored?", !!err)
console.log("Time:", Date.now() - start);
cb(err, result);
});
});
Instance properties
norm.collection
- The raw mongo collection passed in as input
norm.errors
- Exposes the error types that can be returned by store methods.
- These can be created if needed.
- Available types:
NotFound
, Schema
, ObjectId
, Empty
, Operator
, Sharding
, Duplicate
Further work
- Support for
patternProperties