# Mongoose Expressive MongoDB for Node.JS |
## collection | lib/collection.js
Collection constructor ## param: String collection name param: Collection connection object api: public |
    function Collection (name, conn) {
      this.name = name;
      this.conn = conn;
      this.buffer = true;
      this.queue = [];
      if (this.conn.readyState == 1) this.onOpen();
    };
The collection name api: public |
    Collection.prototype.name;
The Connection instance api: public |
    Collection.prototype.conn;
Module exports. |
    module.exports = Collection;
## connection | lib/connection.js
Module dependencies. |
    var url = require('url')
      , utils = require('./utils')
      , EventEmitter = utils.EventEmitter
      , driver = global.MONGOOSE_DRIVER_PATH || './drivers/node-mongodb-native'
      , Model = require('./model')
      , Schema = require('./schema')
      , Collection  = require(driver + '/collection');
Connection constructor. For practical reasons, a Connection equals a Db ## param: Mongoose mongoose base api: public |
    function Connection (base) {
      this.base = base;
      this.collections = {};
      this.models = {};
    };
Inherit from EventEmitter. |
    Connection.prototype.__proto__ = EventEmitter.prototype;
Connection ready state: 0 = Disconnected 1 = Connected 2 = Connecting 3 = Disconnecting api: public |
    Connection.prototype.readyState = 0;
A hash of the collections associated with this connection |
    Connection.prototype.collections;
The mongodb.Db instance, set when the connection is opened api: public |
    Connection.prototype.db;
Establishes the connection `options` is a hash with the following optional properties: options.db - passed to the connection db instance options.server - passed to the connection server instance(s) options.replset - passed to the connection ReplSetServer instance options.user - username for authentication options.pass - password for authentication Notes: Mongoose forces the db option `forceServerObjectId` false and cannot be overridden. Mongoose defaults the server `auto_reconnect` options to true which can be overridden. See the node-mongodb-native driver instance for options that it understands. ## param: String mongodb://uri return: Connection self see: https ://github.com/christkv/node-mongodb-native api: public |
    Connection.prototype.open = function (host, database, port, options, callback) {
      var self = this
        , uri;

      if ('string' === typeof database) {
        switch (arguments.length) {
          case 2:
            port = 27017;
          case 3:
            switch (typeof port) {
              case 'function':
                callback = port, port = 27017;
                break;
              case 'object':
                options = port, port = 27017;
                break;
            }
            break;
          case 4:
            if ('function' === typeof options)
              callback = options, options = {};
        }
      } else {
        switch (typeof database) {
          case 'function':
            callback = database, database = undefined;
            break;
          case 'object':
            options = database;
            database = undefined;
            callback = port;
            break;
        }

        uri = url.parse(host);
        host = uri.hostname;
        port = uri.port || 27017;
        database = uri.pathname &amp;&amp; uri.pathname.replace(/\//g, '');
      }

      callback = callback || noop;
      this.options = this.defaultOptions(options);

      // make sure we can open
      if (0 !== this.readyState) {
        var err = new Error('Trying to open unclosed connection.');
        err.state = this.readyState;
        callback(err);
        return this;
      }

      if (!host) {
        callback(new Error('Missing connection hostname.'));
        return this;
      }

      if (!database) {
        callback(new Error('Missing connection database.'));
        return this;
      }

      // handle authentication
      if (uri &amp;&amp; uri.auth) {
        var auth = uri.auth.split(':');
        this.user = auth[0];
        this.pass = auth[1];

      // Check hostname for user/pass
      } else if (/@/.test(host) &amp;&amp; /:/.test(host.split('@')[0])) {
        host = host.split('@');
        var auth = host.shift().split(':');
        host = host.pop();
        this.user = auth[0];
        this.pass = auth[1];

      // user/pass options
      } else if (options &amp;&amp; options.user &amp;&amp; options.pass) {
        this.user = options.user;
        this.pass = options.pass;

      } else {
        this.user = this.pass = undefined;
      }

      this.name = database;
      this.host = host;
      this.port = port;

      // signal connecting
      this.readyState = 2;
      this.emit('opening');

      // open connection
      this.doOpen(function (err) {
        if (err) {
          self.readyState = 0;
          if (self._events &amp;&amp; self._events.error &amp;&amp;
             ('function' == typeof self._events.error || self._events.error.length)) {
            self.emit(&quot;error&quot;, err);
          }
        } else {
          self.onOpen();
        }

        callback(err || null);
      });

      return this;
    };
Connects to a replica set. Supply a comma-separted list of mongodb:// URIs. You only need to specify the database name and/or auth to one of them. The options parameter is passed to the low level connection. See the node-mongodb-native driver instance for detail. ## param: String comma-separated mongodb:// URIs param: String optional database name param: Object optional options param: Function optional callback |
    Connection.prototype.openSet = function (uris, database, options, callback) {
      var uris = uris.split(',')
        , self = this;

      switch (arguments.length) {
        case 3:
          this.name = database;
          if ('function' === typeof options) callback = options, options = {};
          break;
        case 2:
          switch (typeof database) {
            case 'string':
              this.name = database;
            case 'function':
              callback = database, database = null;
              break;
            case 'object':
              options = database, database = null;
              break;
          }
      }

      this.options = options = this.defaultOptions(options);
      callback = callback || noop;

      if (uris.length &lt; 2) {
        callback(new Error('Please provide comma-separated URIs'));
        return this;
      }

      this.host = [];
      this.port = [];

      uris.forEach(function (uri) {
        var uri = url.parse(uri);

        self.host.push(uri.hostname);
        self.port.push(uri.port || 27017);

        if (!self.name &amp;&amp; uri.pathname.replace(/\//g, ''))
          self.name = uri.pathname.replace(/\//g, '');

        if (!self.user &amp;&amp; uri.auth) {
          var auth = uri.auth.split(':');
          self.user = auth[0];
          self.pass = auth[1];
        }
      });

      if (!this.name) {
        callback(new Error('No database name provided for replica set'));
        return this;
      }

      this.readyState = 2;
      this.emit('opening');

      // open connection
      this.doOpenSet(function (err) {
        if (err) {
          if (self._events &amp;&amp; self._events.error &amp;&amp; self._events.error.length) {
            self.emit(&quot;error&quot;, err);
          }
          self.readyState = 0;
        } else {
          self.onOpen();
        }

        callback(err || null);
      });
    };
Closes the connection ## param: Function optional callback return: Connection self api: public |
    Connection.prototype.close = function (callback) {
      var self = this
        , callback = callback || function(){};

      switch (this.readyState){
        case 0: // disconnected
          callback(null);
          break;

        case 1: // connected
          this.readyState = 3;
          this.doClose(function(err){
            if (err){
              callback(err);
            } else {
              self.onClose();
              callback(null);
            }
          });
          break;

        case 2: // connecting
          this.once('open', function(){
            self.close(callback);
          });
          break;

        case 3: // disconnecting
          this.once('close', function () {
            callback(null);
          });
          break;
      }

      return this;
    };
Retrieves a collection, creating it if not cached. ## param: String collection name return: Collection collection instance api: public |
    Connection.prototype.collection = function (name) {
      if (!(name in this.collections))
        this.collections[name] = new Collection(name, this);
      return this.collections[name];
    };
Defines a model or retrieves it ## param: String model name param: Schema schema object param: String collection name (optional, induced from model name) api: public |
    Connection.prototype.model = function (name, schema, collection) {
      if (!this.models[name]) {
        var model = this.base.model(name, schema, collection, true)
          , Model

        if (this != model.prototype.db) {
          // subclass model using this connection and collection name
          Model = function Model () {
            model.apply(this, arguments);
          };

          Model.__proto__ = model;
          Model.prototype.__proto__ = model.prototype;
          Model.prototype.db = this;

          // collection name discovery
          if ('string' === typeof schema) {
            collection = schema;
          }

          if (!collection) {
            collection = model.prototype.schema.set('collection') || utils.toCollectionName(name);
          }

          Model.prototype.collection = this.collection(collection);
          Model.init();
        }

        this.models[name] = Model || model;
      }

      return this.models[name];
    };
- Set profiling level. ## param: Int | String level - Either off (0), slow (1), or all (2) param: Int [ms] If profiling `level` is set to 1, this determines
                 the threshold in milliseconds above which queries
                 will be logged. Defaults to 100. (optional)
param: Function callback api: public |
    Connection.prototype.setProfiling = function (level, ms, callback) {
      if (1 !== this.readyState) {
        return this.on('open', this.setProfiling.bind(this, level, ms, callback));
      }

      if (!callback) callback = ms, ms = 100;

      var cmd = {};

      switch (level) {
        case 0:
        case 'off':
          cmd.profile = 0;
          break;
        case 1:
        case 'slow':
          cmd.profile = 1;
          if ('number' !== typeof ms) {
            ms = parseInt(ms, 10);
            if (isNaN(ms)) ms = 100;
          }
          cmd.slowms = ms;
          break;
        case 2:
        case 'all':
          cmd.profile = 2;
          break;
        default:
          return callback(new Error('Invalid profiling level: '+ level));
      }

      this.db.executeDbCommand(cmd, function (err, resp) {
        if (err) return callback(err);

        var doc = resp.documents[0];

        err = 1 === doc.ok
          ? null
          : new Error('Could not set profiling level to: '+ level)

        callback(err, doc);
      });
    };
Noop. |
    function noop () {}
Module exports. |
    module.exports = Connection;
## document | lib/document.js
Module dependencies. |
    var EventEmitter = require('events').EventEmitter
      , MongooseError = require('./error')
      , MixedSchema = require('./schema/mixed')
      , Schema = require('./schema')
      , ValidatorError = require('./schematype').ValidatorError
      , utils = require('./utils')
      , clone = utils.clone
      , isMongooseObject = utils.isMongooseObject
      , inspect = require('util').inspect
      , StateMachine = require('./statemachine')
      , ActiveRoster = StateMachine.ctor('require', 'modify', 'init', 'default')
      , deepEqual = utils.deepEqual
      , hooks = require('hooks')
      , DocumentArray
Inherit from EventEmitter. |
    Document.prototype.__proto__ = EventEmitter.prototype;
Base Mongoose instance for the model. Set by the Mongoose instance upon pre-compilation. api: public |
    Document.prototype.base;
Document schema as a nested structure. api: public |
    Document.prototype.schema;
Whether the document is new. api: public |
    Document.prototype.isNew;
Validation errors. api: public |
    Document.prototype.errors;
Sets a path, or many paths ## Examples
    // path, value
    doc.set(path, value)

    // object
    doc.set({
        path  : value
      , path2 : {
           path  : value
        }
    }
## param: String | Object key path, or object param: Object value, or undefined or a prefix if first parameter is an object para: m @optional {Schema|String|...} specify a type if this is an on-the-fly attribute api: public |
    Document.prototype.set = function (path, val, type) {
      var constructing = true === type
        , adhoc = type &amp;&amp; true !== type
        , adhocs

      if (adhoc) {
        adhocs = this._adhocPaths || (this._adhocPaths = {});
        adhocs[path] = Schema.interpretAsType(path, type);
      }

      if ('string' !== typeof path) {
        // new Document({ key: val })

        if (null === path || undefined === path) {
          var _ = path;
          path = val;
          val = _;

        } else {
          var prefix = val
            ? val + '.'
            : '';

          if (path instanceof Document) path = path._doc;

          var keys = Object.keys(path)
            , i = keys.length
            , pathtype
            , key

          while (i--) {
            key = keys[i];
            if (null != path[key] &amp;&amp; 'Object' === path[key].constructor.name
              &amp;&amp; !(this._path(prefix + key) instanceof MixedSchema)) {
              this.set(path[key], prefix + key, constructing);
            } else if (this._strictMode) {
              pathtype = this.schema.pathType(prefix + key);
              if ('real' === pathtype || 'virtual' === pathtype) {
                this.set(prefix + key, path[key], constructing);
              }
            } else if (undefined !== path[key]) {
              this.set(prefix + key, path[key], constructing);
            }
          }

          return this;
        }
      }

      // ensure _strict is honored for obj props
      // docschema = new Schema({ path: { nest: 'string' }})
      // doc.set('path', obj);
      var pathType = this.schema.pathType(path);
      if ('nested' == pathType &amp;&amp; val &amp;&amp; 'Object' == val.constructor.name) {
        this.set(val, path, constructing);
        return this;
      }

      var schema;
      if ('adhocOrUndefined' == pathType &amp;&amp; this._strictMode) {
        return this;
      } else if ('virtual' == pathType) {
        schema = this.schema.virtualpath(path);
        schema.applySetters(val, this);
        return this;
      } else {
        schema = this._path(path);
      }

      var parts = path.split('.')
        , obj = this._doc
        , self = this
        , pathToMark
        , subpaths
        , subpath

      // When using the $set operator the path to the field must already exist.
      // Else mongodb throws: "LEFT_SUBFIELD only supports Object"

      if (parts.length &lt;= 1) {
        pathToMark = path;
      } else {
        subpaths = parts.map(function (part, i) {
          return parts.slice(0, i).concat(part).join('.');
        });

        for (var i = 0, l = subpaths.length; i &lt; l; i++) {
          subpath = subpaths[i];
          if (this.isDirectModified(subpath) // earlier prefixes that are already
                                             // marked as dirty have precedence
              || this.get(subpath) === null) {
            pathToMark = subpath;
            break;
          }
        }

        if (!pathToMark) pathToMark = path;
      }

      if ((!schema || null === val || undefined === val) ||
        this.try(function(){
          // if this doc is being constructed we should not
          // trigger getters.
          var cur = constructing ? undefined : self.get(path);
          var casted = schema.cast(val, self, false, cur);
          val = schema.applySetters(casted, self);
        })) {

        if (this.isNew) {
          this.markModified(pathToMark);
        } else {
          var priorVal = this.get(path);

          if (!this.isDirectModified(pathToMark)) {
            if (undefined === val &amp;&amp; !this.isSelected(path)) {
              // special case:
              // when a path is not selected in a query its initial
              // value will be undefined.
              this.markModified(pathToMark);
            } else if (!deepEqual(val, priorVal)) {
              this.markModified(pathToMark);
            } else if (!constructing &amp;&amp;
                       null != val &amp;&amp;
                       path in this._activePaths.states.default &amp;&amp;
                       deepEqual(val, schema.getDefault(this, constructing))) {
              // special case:
              // a path with a default was $unset on the server
              // and the user is setting it to the same value again
              this.markModified(pathToMark);
            }
          }
        }

        for (var i = 0, l = parts.length; i &lt; l; i++) {
          var next = i + 1
            , last = next === l;

          if (last) {
            obj[parts[i]] = val;
          } else {
            if (obj[parts[i]] &amp;&amp; 'Object' === obj[parts[i]].constructor.name) {
              obj = obj[parts[i]];
            } else if (obj[parts[i]] &amp;&amp; Array.isArray(obj[parts[i]])) {
              obj = obj[parts[i]];
            } else {
              obj = obj[parts[i]] = {};
            }
          }
        }
      }

      return this;
    };
Triggers casting on a specific path tod: o deprecate? not used anywhere ## param: String path api: public |
    Document.prototype.doCast = function (path) {
      var schema = this.schema.path(path);
      if (schema)
        this.setValue(path, this.getValue(path));
    };
Gets a path ## param: String key path para: m @optional {Schema|String|...} specify a type if this is an on-the-fly attribute api: public |
    Document.prototype.get = function (path, type) {
      var adhocs;
      if (type) {
        adhocs = this._adhocPaths || (this._adhocPaths = {});
        adhocs[path] = Schema.interpretAsType(path, type);
      }

      var schema = this._path(path) || this.schema.virtualpath(path)
        , pieces = path.split('.')
        , obj = this._doc;

      for (var i = 0, l = pieces.length; i &lt; l; i++) {
        obj = null == obj ? null : obj[pieces[i]];
      }

      if (schema) {
        obj = schema.applyGetters(obj, this);
      }

      return obj;
    };
Commits a path, marking as modified if needed. Useful for mixed keys api: public |
    Document.prototype.markModified = function (path) {
      this._activePaths.modify(path);
    };
commit Alias on markModified deprecate: d |
    Document.prototype.commit =
      utils.dep('Document#commit'
              , 'Document#markModified'
              , Document.prototype.markModified);
Captures an exception that will be bubbled to `save` ## param: Function function to execute param: Object scope |
    Document.prototype.try = function (fn, scope) {
      var res;
      try {
        fn.call(scope);
        res = true;
      } catch (e) {
        this.error(e);
        res = false;
      }
      return res;
    };
modifiedPaths Returns the list of paths that have been modified. If we set `documents.0.title` to 'newTitle' then `documents`, `documents.0`, and `documents.0.title` are modified. api: public returns: Boolean |
    Document.prototype.__defineGetter__('modifiedPaths', function () {
      var directModifiedPaths = Object.keys(this._activePaths.states.modify);

      return directModifiedPaths.reduce(function (list, path) {
        var parts = path.split('.');
        return list.concat(parts.reduce(function (chains, part, i) {
          return chains.concat(parts.slice(0, i).concat(part).join('.'));
        }, []));
      }, []);
    });
Checks if a path or any full path containing path as part of its path chain has been directly modified. e.g., if we set `documents.0.title` to 'newTitle' then we have directly modified `documents.0.title` but not directly modified `documents` or `documents.0`. Nonetheless, we still say `documents` and `documents.0` are modified. They just are not considered direct modified. The distinction is important because we need to distinguish between what has been directly modified and what hasn't so that we can determine the MINIMUM set of dirty data that we want to send to MongoDB on a Document save. ## param: String path returns: Boolean api: public |
    Document.prototype.isModified = function (path) {
      return !!~this.modifiedPaths.indexOf(path);
    };
Checks if a path has been directly set and modified. False if the path is only part of a larger path that was directly set. e.g., if we set `documents.0.title` to 'newTitle' then we have directly modified `documents.0.title` but not directly modified `documents` or `documents.0`. Nonetheless, we still say `documents` and `documents.0` are modified. They just are not considered direct modified. The distinction is important because we need to distinguish between what has been directly modified and what hasn't so that we can determine the MINIMUM set of dirty data that we want to send to MongoDB on a Document save. ## param: String path returns: Boolean api: public |
    Document.prototype.isDirectModified = function (path) {
      return (path in this._activePaths.states.modify);
    };
Checks if a certain path was initialized ## param: String path returns: Boolean api: public |
    Document.prototype.isInit = function (path) {
      return (path in this._activePaths.states.init);
    };
Checks if a path was selected. ## param: String path return: Boolean api: public |
    Document.prototype.isSelected = function isSelected (path) {
      if (this._selected) {

        if ('_id' === path) {
          return 0 !== this._selected._id;
        }

        var paths = Object.keys(this._selected)
          , i = paths.length
          , inclusive = false
          , cur

        if (1 === i &amp;&amp; '_id' === paths[0]) {
          // only _id was selected.
          return 0 === this._selected._id;
        }

        while (i--) {
          cur = paths[i];
          if ('_id' == cur) continue;
          inclusive = !! this._selected[cur];
          break;
        }

        if (path in this._selected) {
          return inclusive;
        }

        i = paths.length;

        while (i--) {
          cur = paths[i];
          if ('_id' == cur) continue;

          if (0 === cur.indexOf(path + '.')) {
            return inclusive;
          }

          if (0 === (path + '.').indexOf(cur)) {
            return inclusive;
          }
        }

        return ! inclusive;
      }

      return true;
    }
Validation middleware ## param: Function next api: public |
    Document.prototype.validate = function (next) {
      var total = 0
        , self = this
        , validating = {}

      if (!this._activePaths.some('require', 'init', 'modify')) {
        return complete();
      }

      function complete () {
        next(self._validationError);
        self._validationError = null;
      }

      this._activePaths.forEach('require', 'init', 'modify', function validatePath (path) {
        if (validating[path]) return;

        validating[path] = true;
        total++;

        process.nextTick(function(){
          var p = self.schema.path(path);
          if (!p) return --total || complete();

          p.doValidate(self.getValue(path), function (err) {
            if (err) self.invalidate(path, err);
            --total || complete();
          }, self);
        });
      });

      return this;
    };
Marks a path as invalid, causing a subsequent validation to fail. ## param: String path of the field to invalidate param: String | Error error of the path. api: public |
    Document.prototype.invalidate = function (path, err) {
      if (!this._validationError) {
        this._validationError = new ValidationError(this);
      }

      if (!err || 'string' === typeof err) {
        err = new ValidatorError(path, err);
      }

      this._validationError.errors[path] = err;
    }
Returns if the document has been modified ## return: Boolean api: public |
    Document.prototype.__defineGetter__('modified', function () {
      return this._activePaths.some('modify');
    });
Gets the document Available options: getters: apply all getters (path and virtual getters) virtuals: apply virtual getters (can override `getters` option) Example of only applying path getters:
    doc.toObject({ getters: true, virtuals: false })
Example of only applying virtual getters:
    doc.toObject({ virtuals: true })
Example of applying both path and virtual getters:
    doc.toObject({ getters: true })
## return: Object plain object api: public |
    Document.prototype.toObject = function (options) {
      options || (options = {});
      options.minimize = true;

      var ret = clone(this._doc, options);

      if (options.virtuals || options.getters &amp;&amp; false !== options.virtuals) {
        applyGetters(this, ret, 'virtuals', options);
      }

      if (options.getters) {
        applyGetters(this, ret, 'paths', options);
      }

      return ret;
    };
JSON.stringify helper. Implicitly called when a document is passed to JSON.stringify() ## return: Object api: public |
    Document.prototype.toJSON = function (options) {
      if ('undefined' === typeof options) options = {};
      options.json = true;
      return this.toObject(options);
    };
Helper for console.log api: public |
    Document.prototype.toString =
    Document.prototype.inspect = function (options) {
      return inspect(this.toObject(options));
    };
Returns true if the Document stores the same data as doc. ## param: Document doc to compare to return: Boolean api: public |
    Document.prototype.equals = function (doc) {
      return this.get('_id') === doc.get('_id');
    };
Module exports. |
    module.exports = Document;
Document Validation Error |
    function ValidationError (instance) {
      MongooseError.call(this, &quot;Validation failed&quot;);
      Error.captureStackTrace(this, arguments.callee);
      this.name = 'ValidationError';
      this.errors = instance.errors = {};
    };

    ValidationError.prototype.toString = function () {
      return this.name + ': ' + Object.keys(this.errors).map(function (key) {
        return String(this.errors[key]);
      }, this).join(', ');
    };
Inherits from MongooseError. |
    ValidationError.prototype.__proto__ = MongooseError.prototype;

    Document.ValidationError = ValidationError;
Document Error param: text |
    function DocumentError () {
      MongooseError.call(this, msg);
      Error.captureStackTrace(this, arguments.callee);
      this.name = 'DocumentError';
    };
Inherits from MongooseError. |
    DocumentError.prototype.__proto__ = MongooseError.prototype;

    exports.Error = DocumentError;
## binary | lib/drivers/node-mongodb-native/binary.js
Module dependencies. |
    var Binary = require('mongodb').BSONPure.Binary;

    module.exports = exports = Binary;
## collection | lib/drivers/node-mongodb-native/collection.js
Module dependencies. |
    var Collection = require('../../collection')
      , NativeCollection = require('mongodb').Collection
      , utils = require('../../utils')
Inherit from abstract Collection. |
    MongooseCollection.prototype.__proto__ = Collection.prototype;
Copy the collection methods and make them subject to queues |
    for (var i in NativeCollection.prototype)
      (function(i){
        MongooseCollection.prototype[i] = function () {
          // BENCHMARKME: is it worth caching the prototype methods? probably
          if (!this.buffer) {
            var collection = this.collection
              , args = arguments
              , self = this;

            process.nextTick(function(){
              var debug = self.conn.base.options.debug;

              if (debug) {
                if ('function' === typeof debug) {
                  debug.apply(debug
                    , [self.name, i].concat(utils.args(args, 0, args.length-1)));
                } else {
                  console.error('\x1B[0;36mMongoose:\x1B[0m %s.%s(%s) %s %s %s'
                    , self.name
                    , i
                    , print(args[0])
                    , print(args[1])
                    , print(args[2])
                    , print(args[3]))
                }
              }

              collection[i].apply(collection, args);
            });
          } else {
            this.addQueue(i, arguments);
          }
        };
      })(i);
Override signature of ensureIndex. -native one is not standard. ## param: Object spec param: Object options param: Function callback api: public |
    var oldEnsureIndex = NativeCollection.prototype.ensureIndex;

    function noop () {};

    NativeCollection.prototype.ensureIndex = function(fields, options, fn){
      if (!this.buffer) {
        return oldEnsureIndex.apply(this, arguments);
      }
    };
Module exports. |
    module.exports = MongooseCollection;
## connection | lib/drivers/node-mongodb-native/connection.js
Module dependencies. |
    var Connection = require('../../connection')
      , mongo = require('mongodb')
      , Server = mongo.Server
      , ReplSetServers = mongo.ReplSetServers;
Inherits from Connection. |
    NativeConnection.prototype.__proto__ = Connection.prototype;
Module exports. |
    module.exports = NativeConnection;
## objectid | lib/drivers/node-mongodb-native/objectid.js
Module dependencies. |
    var ObjectId = require('mongodb').BSONPure.ObjectID;
## error | lib/error.js
Inherits from Error. |
    MongooseError.prototype.__proto__ = Error.prototype;
Module exports. |
    module.exports = MongooseError;
## index | lib/index.js
Module dependencies. |
    var Schema = require('./schema')
      , SchemaType = require('./schematype')
      , VirtualType = require('./virtualtype')
      , SchemaTypes = Schema.Types
      , SchemaDefaults = require('./schemadefault')
      , Types = require('./types')
      , Query = require('./query')
      , Promise = require('./promise')
      , Model = require('./model')
      , Document = require('./document')
      , utils = require('./utils');
Mongoose constructor. Most apps will only use one instance. api: public |
    function Mongoose () {
      this.connections = [];
      this.plugins = [];
      this.models = {};
      this.modelSchemas = {};
      this.options = {};
      this.createConnection(); // default connection
    };
Sets/gets mongoose options ## Examples mongoose.set('test') // returns the 'test' value mongoose.set('test', value) // sets the 'test' value ## param: String key param: String value api: public |
    Mongoose.prototype.set =
    Mongoose.prototype.get = function (key, value) {
      if (arguments.length == 1)
        return this.options[key];
      this.options[key] = value;
      return this;
    };
Creates a Connection instance. ## Examples // with mongodb:// URI db = mongoose.createConnection('mongodb://localhost:port/database'); // with [host, database_name[, port] signature db = mongoose.createConnection('localhost', 'database', port) // initialize now, connect later db = mongoose.createConnection(); db.open('localhost', 'database', port); ## param: String mongodb:// URI return: Connection the created Connection object api: public |
    Mongoose.prototype.createConnection = function () {
      var conn = new Connection(this);
      this.connections.push(conn);
      if (arguments.length)
        conn.open.apply(conn, arguments);
      return conn;
    };
Creates a replica set connection ## see: Mongoose#createConnection api: public deprecate: d |
    function createSetConnection () {
      var conn = new Connection(this);
      this.connections.push(conn);
      if (arguments.length)
        conn.openSet.apply(conn, arguments);
      return conn;
    };

    Mongoose.prototype.createSetConnection =
      utils.dep('Mongoose#createSetConnection'
              , 'Mongoose#createConnection in v3'
              , createSetConnection);
Connects the default mongoose connection ## see: Mongoose#createConnection api: public |
    Mongoose.prototype.connect = function (){
      this.connection.open.apply(this.connection, arguments);
      return this;
    };
Connects the default mongoose connection to a replica set ## see: Mongoose#createSetConnection api: public deprecate: d |
    function connectSet () {
      this.connection.openSet.apply(this.connection, arguments);
      return this;
    };
    Mongoose.prototype.connectSet =
      utils.dep('Mongoose#connectSet', 'Mongoose#connect in v3', connectSet);
Disconnects from all connections. ## param: Function optional callback api: public |
    Mongoose.prototype.disconnect = function (fn) {
      var count = this.connections.length;
      this.connections.forEach(function(conn){
        conn.close(function(err){
          if (err) return fn(err);
          if (fn)
            --count || fn();
        });
      });
      return this;
    };
Defines a model or retrieves it ## param: String model name param: Schema schema object param: String collection name (optional, induced from model name) param: Boolean whether to skip initialization (defaults to false) api: public |
    Mongoose.prototype.model = function (name, schema, collection, skipInit) {
      // normalize collection
      if (!(schema instanceof Schema)) {
        collection = schema;
        schema = false;
      }

      if ('boolean' === typeof collection) {
        skipInit = collection;
        collection = null;
      }

      // look up models for the collection
      if (!this.modelSchemas[name]) {
        if (!schema &amp;&amp; name in SchemaDefaults) {
          schema = SchemaDefaults[name];
        }

        if (schema) {
          this.modelSchemas[name] = schema;
          for (var i = 0, l = this.plugins.length; i &lt; l; i++) {
            schema.plugin(this.plugins[i][0], this.plugins[i][1]);
          }
        } else {
          throw new Error(t been registered for model &quot;' + name + '&quot;.\n'
                        + 'Use mongoose.model(name, schema)');
        }
      }

      if (!schema) {
        schema = this.modelSchemas[name];
      }

      if (!collection) {
        collection = schema.set('collection') || utils.toCollectionName(name);
      }

      if (!this.models[name]) {
        var model = Model.compile(name
                            , this.modelSchemas[name]
                            , collection
                            , this.connection
                            , this);

        if (!skipInit) model.init();

        this.models[name] = model;
      }

      return this.models[name];
    };
Declares a plugin executed on Schemas. Equivalent to calling `.plugin(fn)` on each Schema you create. ## param: Function plugin callback api: public |
    Mongoose.prototype.plugin = function (fn, opts) {
      this.plugins.push([fn, opts]);
      return this;
    };
Default connection api: public |
    Mongoose.prototype.__defineGetter__('connection', function(){
      return this.connections[0];
    });
Driver depentend APIs |
    var driver = global.MONGOOSE_DRIVER_PATH || './drivers/node-mongodb-native';
Connection api: public |
    var Connection = require(driver + '/connection');
Collection api: public |
    var Collection = require(driver + '/collection');
Export default singleton. api: public |
    module.exports = exports = new Mongoose();
Collection api: public |
    exports.Collection = Collection;
Connection api: public |
    exports.Connection = Connection;
Exports Mongoose version param: version |
    exports.version = JSON.parse(
      require('fs').readFileSync(__dirname + '/../package.json', 'utf8')
    ).version;
Export Mongoose constructor api: public |
    exports.Mongoose = Mongoose;
Export Schema constructor api: public |
    exports.Schema = Schema;
Export SchemaType constructor. api: public |
    exports.SchemaType = SchemaType;
Export VirtualType constructor. api: public |
    exports.VirtualType = VirtualType;
Export Schema types api: public |
    exports.SchemaTypes = SchemaTypes;
Export types api: public |
    exports.Types = Types;
Export Query api: public |
    exports.Query = Query;
Export Promise api: public |
    exports.Promise = Promise;
Export Model constructor api: public |
    exports.Model = Model;
Export Document constructor api: public |
    exports.Document = Document;
Export MongooseError api: public |
    exports.Error = require('./error');

    exports.mongo = require('mongodb');
## model | lib/model.js
Module dependencies. |
    var Document = require('./document')
      , MongooseArray = require('./types/array')
      , MongooseBuffer = require('./types/buffer')
      , MongooseError = require('./error')
      , Query = require('./query')
      , utils = require('./utils')
      , isMongooseObject = utils.isMongooseObject
      , EventEmitter = utils.EventEmitter
      , merge = utils.merge
      , Promise = require('./promise')
      , tick = utils.tick
Model constructor ## param: Object values to set api: public |
    function Model (doc, fields) {
      Document.call(this, doc, fields);
    };
Inherits from Document. |
    Model.prototype.__proto__ = Document.prototype;
Connection the model uses. Set by the Connection or if absent set to the default mongoose connection; api: public |
    Model.prototype.db;
Collection the model uses. Set by Mongoose instance api: public |
    Model.prototype.collection;
Model name. api: public |
    Model.prototype.modelName;
Saves this document. see: Model #registerHooks ## param: Function fn api: public |
    Model.prototype.save = function save (fn) {
      var promise = new Promise(fn)
        , complete = handleSave(promise, this)
        , options = {}

      if (this.options.safe) {
        options.safe = this.options.safe;
      }

      if (this.isNew) {
        // send entire doc
        this.collection.insert(this.toObject({ depopulate: 1 }), options, complete);
        this._reset();
        this.isNew = false;
        this.emit('isNew', false);
        // Make it possible to retry the insert
        this._inserting = true;

      } else {
        // Make sure we don't treat it as a new object on error,
        // since it already exists
        this._inserting = false;

        var delta = this._delta();
        this._reset();

        if (delta) {
          var where = this._where();
          this.collection.update(where, delta, options, complete);
        } else {
          complete(null);
        }

        this.emit('isNew', false);
      }
    };
Remove the document ## param: Function callback api: public |
    Model.prototype.remove = function remove (fn) {
      if (this._removing) return this;

      var promise = this._removing = new Promise(fn)
        , where = this._where()
        , self = this
        , options = {}

      if (this.options.safe) {
        options.safe = this.options.safe;
      }

      this.collection.remove(where, options, tick(function (err) {
        if (err) {
          promise.error(err);
          promise = self = self._removing = where = options = null;
          return;
        }
        promise.complete();
        self.emit('remove', self);
        promise = self = where = options = null;
      }));

      return this;
    };
Shortcut to access another model. ## param: String model name api: public |
    Model.prototype.model = function model (name) {
      return this.db.model(name);
    };
Give the constructor the ability to emit events. |
    for (var i in EventEmitter.prototype)
      Model[i] = EventEmitter.prototype[i];
Document schema api: public |
    Model.schema;
Database instance the model uses. api: public |
    Model.db;
Collection the model uses. api: public |
    Model.collection;
Define properties that access the prototype. |
    ['db', 'collection', 'schema', 'options', 'model'].forEach(function(prop){
      Model.__defineGetter__(prop, function(){
        return this.prototype[prop];
      });
    });
Module exports. |
    module.exports = exports = Model;

    Model.remove = function remove (conditions, callback) {
      if ('function' === typeof conditions) {
        callback = conditions;
        conditions = {};
      }

      var query = new Query(conditions).bind(this, 'remove');

      if ('undefined' === typeof callback)
        return query;

      this._applyNamedScope(query);
      return query.remove(callback);
    };
Finds documents ## Examples // retrieve only certain keys MyModel.find({ name: /john/i }, ['name', 'friends'], function () { }) // pass options MyModel.find({ name: /john/i }, [], { skip: 10 } ) ## param: Object conditions param: Object | Function (optional) fields to hydrate or callback param: Function callback api: public |
    Model.find = function find (conditions, fields, options, callback) {
      if ('function' == typeof conditions) {
        callback = conditions;
        conditions = {};
        fields = null;
        options = null;
      } else if ('function' == typeof fields) {
        callback = fields;
        fields = null;
        options = null;
      } else if ('function' == typeof options) {
        callback = options;
        options = null;
      }

      var query = new Query(conditions, options);
      query.bind(this, 'find');
      query.select(fields);

      if ('undefined' === typeof callback)
        return query;

      this._applyNamedScope(query);
      return query.find(callback);
    };
Finds by id ## param: ObjectId | Object objectid, or a value that can be casted to it api: public |
    Model.findById = function findById (id, fields, options, callback) {
      return this.findOne({ _id: id }, fields, options, callback);
    };
Finds one document ## param: Object conditions param: Object | Function (optional) fields to hydrate or callback param: Function callback api: public |
    Model.findOne = function findOne (conditions, fields, options, callback) {
      if ('function' == typeof options) {
        // TODO Handle all 3 of the following scenarios
        // Hint: Only some of these scenarios are possible if cQuery is present
        // Scenario: findOne(conditions, fields, callback);
        // Scenario: findOne(fields, options, callback);
        // Scenario: findOne(conditions, options, callback);
        callback = options;
        options = null;
      } else if ('function' == typeof fields) {
        // TODO Handle all 2 of the following scenarios
        // Scenario: findOne(conditions, callback)
        // Scenario: findOne(fields, callback)
        // Scenario: findOne(options, callback);
        callback = fields;
        fields = null;
        options = null;
      } else if ('function' == typeof conditions) {
        callback = conditions;
        conditions = {};
        fields = null;
        options = null;
      }

      var query = new Query(conditions, options).select(fields).bind(this, 'findOne');

      if ('undefined' == typeof callback)
        return query;

      this._applyNamedScope(query);
      return query.findOne(callback);
    };
Counts documents ## param: Object conditions param: Function optional callback api: public |
    Model.count = function count (conditions, callback) {
      if ('function' === typeof conditions)
        callback = conditions, conditions = {};

      var query = new Query(conditions).bind(this, 'count');
      if ('undefined' == typeof callback)
        return query;

      this._applyNamedScope(query);
      return query.count(callback);
    };

    Model.distinct = function distinct (field, conditions, callback) {
      var query = new Query(conditions).bind(this, 'distinct');
      if ('undefined' == typeof callback) {
        query._distinctArg = field;
        return query;
      }

      this._applyNamedScope(query);
      return query.distinct(field, callback);
    };
`where` enables a very nice sugary api for doing your queries. For example, instead of writing: User.find({age: {$gte: 21, $lte: 65}}, callback); we can instead write more readably: User.where('age').gte(21).lte(65); Moreover, you can also chain a bunch of these together like: User .where('age').gte(21).lte(65) .where('name', /^b/i) // All names that begin where b or B .where('friends').slice(10); ## param: String path param: Object val (optional) return: Query api: public |
    Model.where = function where (path, val) {
      var q = new Query().bind(this, 'find');
      return q.where.apply(q, arguments);
    };
Sometimes you need to query for things in mongodb using a JavaScript expression. You can do so via find({$where: javascript}), or you can use the mongoose shortcut method $where via a Query chain or from your mongoose Model. ## param: String | Function js is a javascript string or anonymous function return: Query api: public |
    Model.$where = function $where () {
      var q = new Query().bind(this, 'find');
      return q.$where.apply(q, arguments);
    };
Shortcut for creating a new Document that is automatically saved to the db if valid. ## param: Object doc param: Function callback api: public |
    Model.create = function create (doc, fn) {
      if (1 === arguments.length) {
        return 'function' === typeof doc &amp;&amp; doc(null);
      }

      var self = this
        , docs = [null]
        , promise
        , count
        , args

      if (Array.isArray(doc)) {
        args = doc;
      } else {
        args = utils.args(arguments, 0, arguments.length - 1);
        fn = arguments[arguments.length - 1];
      }

      if (0 === args.length) return fn(null);

      promise = new Promise(fn);
      count = args.length;

      args.forEach(function (arg, i) {
        var doc = new self(arg);
        docs[i+1] = doc;
        doc.save(function (err) {
          if (err) return promise.error(err);
          --count || fn.apply(null, docs);
        });
      });

      // TODO
      // utilize collection.insertAll for batch processing?
    };
Updates documents. ## Examples
    MyModel.update({ age: { $gt: 18 } }, { oldEnough: true }, fn);
    MyModel.update({ name: 'Tobi' }, { ferret: true }, { multi: true }, fn);
Valid options: safe (boolean) safe mode (defaults to value set in schema (true)) upsert (boolean) whether to create the doc if it doesn't match (false) multi (boolean) whether multiple documents should be updated (false) ## param: Object conditions param: Object doc param: Object options param: Function callback return: Query api: public |
    Model.update = function update (conditions, doc, options, callback) {
      if (arguments.length &lt; 4) {
        if ('function' === typeof options) {
          // Scenario: update(conditions, doc, callback)
          callback = options;
          options = null;
        } else if ('function' === typeof doc) {
          // Scenario: update(doc, callback);
          callback = doc;
          doc = conditions;
          conditions = {};
          options = null;
        }
      }

      var query = new Query(conditions, options).bind(this, 'update', doc);

      if ('undefined' == typeof callback)
        return query;

      this._applyNamedScope(query);
      return query.update(doc, callback);
    };
## namedscope | lib/namedscope.js
var Query = require('./query'); function NamedScope () {} NamedScope.prototype.query; NamedScope.prototype.where = function () { var q = this.query || (this.query = new Query()); q.where.apply(q, arguments); return q; }; |
    *
     * Decorate
     *
     * @param {NamedScope} target
     * @param {Object} getters
     * @api private
NamedScope.prototype.decorate = function (target, getters) { var name = this.name , block = this.block , query = this.query; if (block) { if (block.length === 0) { Object.defineProperty(target, name, { get: getters.block0(block) }); } else { target[name] = getters.blockN(block); } } else { Object.defineProperty(target, name, { get: getters.basic(query) }); } }; NamedScope.prototype.compile = function (model) { var allScopes = this.scopesByName , scope; for (var k in allScopes) { scope = allScopes[k]; scope.decorate(model, { block0: function (block) { return function () { var cquery = this.cumulativeQuery || (this.cumulativeQuery = new Query().bind(this)); block.call(cquery); return this; }; }, blockN: function (block) { return function () { var cquery = this.cumulativeQuery || (this.cumulativeQuery = new Query().bind(this)); block.apply(cquery, arguments); return this; }; }, basic: function (query) { return function () { var cquery = this.cumulativeQuery || (this.cumulativeQuery = new Query().bind(this)); cquery.find(query); return this; }; } }); } }; module.exports = NamedScope; |
## promise | lib/promise.js
Module dependencies. |
    var util = require('./utils');
    var EventEmitter = util.EventEmitter;
Promise constructor. ## param: Function a callback+errback that takes err, ... as signature api: public |
    function Promise (back) {
      this.emitted = {};
      if ('function' == typeof back)
        this.addBack(back);
    };
Inherits from EventEmitter. |
    Promise.prototype.__proto__ = EventEmitter.prototype;
Adds an event or fires the callback right away. return: promise api: public |
    Promise.prototype.on = function (event, callback) {
      if (this.emitted[event])
        callback.apply(this, this.emitted[event]);
      else
        EventEmitter.prototype.on.call(this, event, callback);

      return this;
    };
Shortcut for emitting complete event api: public |
    Promise.prototype.complete = function () {
      var args = util.args(arguments);
      return this.emit.apply(this, ['complete'].concat(args));
    };
Shortcut for emitting err event api: public |
    Promise.prototype.error = function (err) {
      if (!(err instanceof Error)) err = new Error(err);
      return this.emit('err', err);
    };
Shortcut for `.on('complete', fn)` return: promise api: public |
    Promise.prototype.addCallback = function (fn) {
      return this.on('complete', fn);
    };
Shortcut for `.on('err', fn)` return: promise api: public |
    Promise.prototype.addErrback = function (fn) {
      return this.on('err', fn);
    };
Sugar for handling cases where you may be resolving to either an error condition or a success condition. ## param: Error optional error or null param: Object value to complete the promise with api: public |
    Promise.prototype.resolve = function (err, val) {
      if (err) return this.error(err);
      return this.complete(val);
    };
Module exports. |
    module.exports = Promise;
## querystream | lib/querystream.js
Module dependencies. |
    var Stream = require('stream').Stream
    var utils = require('./utils')
QueryStream Returns a stream interface for the `query`. ## param: Query query return: Stream |
    function QueryStream (query) {
      Stream.call(this);

      this.query = query;
      this.readable = true;
      this.paused = false;
      this._cursor = null;
      this._destroyed = null;
      this._fields = null;
      this._ticks = 0;
      this._inline = T_INIT;

      // give time to hook up events
      var self = this;
      process.nextTick(function () {
        self._init();
      });
    }
Flag stating whether or not this stream is readable. |
    QueryStream.prototype.readable;
Flag stating whether or not this stream is paused. |
    QueryStream.prototype.paused;

    // trampoline flags
    var T_INIT = 0;
    var T_IDLE = 1;
    var T_CONT = 2;
Pauses this stream. |
    QueryStream.prototype.pause = function () {
      this.paused = true;
    }
Resumes this stream. |
    QueryStream.prototype.resume = function () {
      this.paused = false;
      this._next();
    }
Destroys the stream, closing the underlying cursor. No more events will be emitted. |
    QueryStream.prototype.destroy = function (err) {
      if (this._destroyed) return;
      this._destroyed = true;
      this.readable = false;

      if (this._cursor) {
        this._cursor.close();
      }

      if (err) {
        this.emit('error', err);
      }

      this.emit('close');
    }

    // TODO - maybe implement the -native raw option to pass binary?
    //QueryStream.prototype.setEncoding = function () {
    //}

    module.exports = exports = QueryStream;
## query | lib/query.js
Module dependencies. |
    var utils = require('./utils')
      , merge = utils.merge
      , Promise = require('./promise')
      , Document = require('./document')
      , inGroupsOf = utils.inGroupsOf
      , tick = utils.tick
      , QueryStream = require('./querystream')
Binds this query to a model. ## param: Function param return: Query api: public |
    Query.prototype.bind = function bind (model, op, updateArg) {
      this.model = model;
      this.op = op;
      if (op === 'update') this._updateArg = updateArg;
      return this;
    };
Executes the query returning a promise. ## Examples query.exec(); query.exec(callback); query.exec('update'); query.exec('find', callback); ## param: String | Function op (optional) param: Function callback (optional) return: Promise api: public |
    Query.prototype.exec = function (op, callback) {
      var promise = new Promise();

      switch (typeof op) {
        case 'function':
          callback = op;
          op = null;
          break;
        case 'string':
          this.op = op;
          break;
      }

      if (callback) promise.addBack(callback);

      if (!this.op) {
        promise.complete();
        return promise;
      }

      if ('update' == this.op) {
        this.update(this._updateArg, promise.resolve.bind(promise));
        return promise;
      }

      if ('distinct' == this.op) {
        this.distinct(this._distinctArg, promise.resolve.bind(promise));
        return promise;
      }

      this[this.op](promise.resolve.bind(promise));
      return promise;
    };
Finds documents. ## param: Object criteria param: Function callback api: public |
    Query.prototype.find = function (criteria, callback) {
      this.op = 'find';
      if ('function' === typeof criteria) {
        callback = criteria;
        criteria = {};
      } else if (criteria instanceof Query) {
        // TODO Merge options, too
        merge(this._conditions, criteria._conditions);
      } else if (criteria instanceof Document) {
        merge(this._conditions, criteria.toObject());
      } else if (criteria &amp;&amp; 'Object' === criteria.constructor.name) {
        merge(this._conditions, criteria);
      }
      if (!callback) return this;
      return this.execFind(callback);
    };
Casts obj, or if obj is not present, then this._conditions, based on the model's schema. ## param: Function model param: Object obj (optional) api: public |
    Query.prototype.cast = function (model, obj) {
      obj || (obj= this._conditions);

      var schema = model.schema
        , paths = Object.keys(obj)
        , i = paths.length
        , any$conditionals
        , schematype
        , nested
        , path
        , type
        , val;

      while (i--) {
        path = paths[i];
        val = obj[path];

        if ('$or' === path || '$nor' === path) {
          var k = val.length
            , orComponentQuery;

          while (k--) {
            orComponentQuery = new Query(val[k]);
            orComponentQuery.cast(model);
            val[k] = orComponentQuery._conditions;
          }

        } else if (path === '$where') {
          type = typeof val;

          if ('string' !== type &amp;&amp; 'function' !== type) {
            throw new Error(&quot;Must have a string or function for $where&quot;);
          }

          if ('function' === type) {
            obj[path] = val.toString();
          }

          continue;

        } else {

          if (!schema) {
            // no casting for Mixed types
            continue;
          }

          schematype = schema.path(path);

          if (!schematype) {
            // Handle potential embedded array queries
            var split = path.split('.')
              , j = split.length
              , pathFirstHalf
              , pathLastHalf
              , remainingConds
              , castingQuery;

            // Find the part of the var path that is a path of the Schema
            while (j--) {
              pathFirstHalf = split.slice(0, j).join('.');
              schematype = schema.path(pathFirstHalf);
              if (schematype) break;
            }

            // If a substring of the input path resolves to an actual real path...
            if (schematype) {
              // Apply the casting; similar code for $elemMatch in schema/array.js
              if (schematype.caster &amp;&amp; schematype.caster.schema) {
                remainingConds = {};
                pathLastHalf = split.slice(j).join('.');
                remainingConds[pathLastHalf] = val;
                castingQuery = new Query(remainingConds);
                castingQuery.cast(schematype.caster);
                obj[path] = castingQuery._conditions[pathLastHalf];
              } else {
                obj[path] = val;
              }
            }

          } else if (val === null || val === undefined) {
            continue;
          } else if ('Object' === val.constructor.name) {

            any$conditionals = Object.keys(val).some(function (k) {
              return k.charAt(0) === '$' &amp;&amp; k !== '$id' &amp;&amp; k !== '$ref';
            });

            if (!any$conditionals) {
              obj[path] = schematype.castForQuery(val);
            } else {

              var ks = Object.keys(val)
                , k = ks.length
                , $cond;

              while (k--) {
                $cond = ks[k];
                nested = val[$cond];

                if ('$exists' === $cond) {
                  if ('boolean' !== typeof nested) {
                    throw new Error(&quot;$exists parameter must be Boolean&quot;);
                  }
                  continue;
                }

                if ('$type' === $cond) {
                  if ('number' !== typeof nested) {
                    throw new Error(&quot;$type parameter must be Number&quot;);
                  }
                  continue;
                }

                if ('$not' === $cond) {
                  this.cast(model, nested);
                } else {
                  val[$cond] = schematype.castForQuery($cond, nested);
                }
              }
            }
          } else {
            obj[path] = schematype.castForQuery(val);
          }
        }
      }
    };
Sometimes you need to query for things in mongodb using a JavaScript expression. You can do so via find({$where: javascript}), or you can use the mongoose shortcut method $where via a Query chain or from your mongoose Model. ## param: String | Function js is a javascript string or anonymous function return: Query api: public |
    Query.prototype.$where = function (js) {
      this._conditions['$where'] = js;
      return this;
    };
`where` enables a very nice sugary api for doing your queries. For example, instead of writing:
    User.find({age: {$gte: 21, $lte: 65}}, callback);
we can instead write more readably:
    User.where('age').gte(21).lte(65);
Moreover, you can also chain a bunch of these together like:
    User
      .where('age').gte(21).lte(65)
      .where('name', /^b/i)        // All names that begin where b or B
      .where('friends').slice(10);
## param: String path param: Object val (optional) return: Query api: public |
    Query.prototype.where = function (path, val) {
      if (2 === arguments.length) {
        this._conditions[path] = val;
      }
      this._currPath = path;
      return this;
    };
`equals` sugar.
    User.where('age').equals(49);
Same as
    User.where('age', 49);
## param: object val return: Query api: public |
    Query.prototype.equals = function equals (val) {
      var path = this._currPath;
      if (!path) throw new Error('equals() must be used after where()');
      this._conditions[path] = val;
      return this;
    }
or |
    Query.prototype.or = function or (array) {
      var or = this._conditions.$or || (this._conditions.$or = []);
      if (!Array.isArray(array)) array = [array];
      or.push.apply(or, array);
      return this;
    }
nor |
    Query.prototype.nor = function nor (array) {
      var nor = this._conditions.$nor || (this._conditions.$nor = []);
      if (!Array.isArray(array)) array = [array];
      nor.push.apply(nor, array);
      return this;
    }
gt, gte, lt, lte, ne, in, nin, all, regex, size, maxDistance Can be used on Numbers or Dates.
    Thing.where('type').nin(array)
    'gt gte lt lte ne in nin all regex size maxDistance'.split(' ').forEach(function ($conditional) {
      Query.prototype[$conditional] = function (path, val) {
        if (arguments.length === 1) {
          val = path;
          path = this._currPath
        }
        var conds = this._conditions[path] || (this._conditions[path] = {});
        conds['$' + $conditional] = val;
        return this;
      };

      // deprecationed
      Query.prototype['$' + $conditional] = utils.dep('Query#$'+ $conditional, 'Query#' + $conditional, Query.prototype[$conditional]);
    });
mod, near |
    ;['mod', 'near'].forEach( function ($conditional) {
      Query.prototype[$conditional] = function (path, val) {
        if (arguments.length === 1) {
          val = path;
          path = this._currPath
        } else if (arguments.length === 2 &amp;&amp; !Array.isArray(val)) {
          val = utils.args(arguments);
          path = this._currPath;
        } else if (arguments.length === 3) {
          val = utils.args(arguments, 1);
        }
        var conds = this._conditions[path] || (this._conditions[path] = {});
        conds['$' + $conditional] = val;
        return this;
      };
    });
exists |
    Query.prototype.exists = function (path, val) {
      if (arguments.length === 0) {
        path = this._currPath
        val = true;
      } else if (arguments.length === 1) {
        if ('boolean' === typeof path) {
          val = path;
          path = this._currPath;
        } else {
          val = true;
        }
      }
      var conds = this._conditions[path] || (this._conditions[path] = {});
      conds['$exists'] = val;
      return this;
    };
elemMatch |
    Query.prototype.elemMatch = function (path, criteria) {
      var block;
      if ('Object' === path.constructor.name) {
        criteria = path;
        path = this._currPath;
      } else if ('function' === typeof path) {
        block = path;
        path = this._currPath;
      } else if ('Object' === criteria.constructor.name) {
      } else if ('function' === typeof criteria) {
        block = criteria;
      } else {
        throw new Error(&quot;Argument error&quot;);
      }
      var conds = this._conditions[path] || (this._conditions[path] = {});
      if (block) {
        criteria = new Query();
        block(criteria);
        conds['$elemMatch'] = criteria._conditions;
      } else {
        conds['$elemMatch'] = criteria;
      }
      return this;
    };
Spatial queries |
    Object.defineProperty(Query.prototype, 'within', {
      get: function () { return this }
    });

    Query.prototype.box = function (path, val) {
      if (arguments.length === 1) {
        val = path;
        path = this._currPath;
      }
      var conds = this._conditions[path] || (this._conditions[path] = {});
      conds['$within'] = { '$box': [val.ll, val.ur]  };
      return this;
    };

    Query.prototype.center = function (path, val) {
      if (arguments.length === 1) {
        val = path;
        path = this._currPath;
      }
      var conds = this._conditions[path] || (this._conditions[path] = {});
      conds['$within'] = { '$center': [val.center, val.radius]  };
      return this;
    };

    Query.prototype.centerSphere = function (path, val) {
      if (arguments.length === 1) {
        val = path;
        path = this._currPath;
      }
      var conds = this._conditions[path] || (this._conditions[path] = {});
      conds['$within'] = { '$centerSphere': [val.center, val.radius]  };
      return this;
    };
select Chainable method for specifying which fields to include or exclude from the document that is returned from MongoDB. ## Examples
    query.fields({a: 1, b: 1, c: 1, _id: 0});
    query.fields('a b c');
## param: Object |
    Query.prototype.select = function () {
      var arg0 = arguments[0];
      if (!arg0) return this;
      if ('Object' === arg0.constructor.name || Array.isArray(arg0)) {
        this._applyFields(arg0);
      } else if (arguments.length === 1 &amp;&amp; typeof arg0 === 'string') {
        this._applyFields({only: arg0});
      } else {
        this._applyFields({only: this._parseOnlyExcludeFields.apply(this, arguments)});
      }
      return this;
    };
slice() |
    Query.prototype.slice = function (path, val) {
      if (arguments.length === 1) {
          val = path;
          path = this._currPath
      } else if (arguments.length === 2) {
        if ('number' === typeof path) {
          val = [path, val];
          path = this._currPath;
        }
      } else if (arguments.length === 3) {
        val = utils.args(arguments, 1);
      }
      var myFields = this._fields || (this._fields = {});
      myFields[path] = { '$slice': val };
      return this;
    };
sort Sets the sort ## Examples
    query.sort('test', 1)
    query.sort('field', -1)
    query.sort('field', -1, 'test', 1)
api: public |
    Query.prototype.sort = function () {
      var sort = this.options.sort || (this.options.sort = []);

      inGroupsOf(2, arguments, function (field, value) {
        sort.push([field, value]);
      });

      return this;
    };

    ;['limit', 'skip', 'maxscan', 'snapshot', 'batchSize', 'comment'].forEach( function (method) {
      Query.prototype[method] = function (v) {
        this.options[method] = v;
        return this;
      };
    });
hint Sets query hints. ## Examples
    new Query().hint({ indexA: 1, indexB: -1})
    new Query().hint("indexA", 1, "indexB", -1)
## param: Object | String v param: Int [multi] return: Query api: public |
    Query.prototype.hint = function (v, multi) {
      var hint = this.options.hint || (this.options.hint = {})
        , k

      if (multi) {
        inGroupsOf(2, arguments, function (field, val) {
          hint[field] = val;
        });
      } else if ('Object' === v.constructor.name) {
        // must keep object keys in order so don't use Object.keys()
        for (k in v) {
          hint[k] = v[k];
        }
      }

      return this;
    };
slaveOk Sets slaveOk option.
    new Query().slaveOk() <== true
    new Query().slaveOk(true)
    new Query().slaveOk(false)
## param: Boolean v (defaults to true) api: public |
    Query.prototype.slaveOk = function (v) {
      this.options.slaveOk = arguments.length ? !!v : true;
      return this;
    };
tailable Sets tailable option.
    new Query().tailable() <== true
    new Query().tailable(true)
    new Query().tailable(false)
## param: Boolean v (defaults to true) api: public |
    Query.prototype.tailable = function (v) {
      this.options.tailable = arguments.length ? !!v : true;
      return this;
    };
findOne Casts the query, sends the findOne command to mongodb. Upon receiving the document, we initialize a mongoose document based on the returned document from mongodb, and then we invoke a callback on our mongoose document. ## param: Function callback function (err, found) api: public |
    Query.prototype.findOne = function (callback) {
      this.op = 'findOne';

      if (!callback) return this;

      var model = this.model;
      var promise = new Promise(callback);

      try {
        this.cast(model);
      } catch (err) {
        promise.error(err);
        return this;
      }

      // apply default schematype path selections
      this._applyPaths();

      var self = this
        , castQuery = this._conditions
        , options = this._optionsForExec(model)

      var fields = utils.clone(options.fields = this._fields);

      model.collection.findOne(castQuery, options, tick(function (err, doc) {
        if (err) return promise.error(err);
        if (!doc) return promise.complete(null);

        var casted = new model(undefined, fields);

        // skip _id for pre-init hooks
        delete casted._doc._id;

        casted.init(doc, self, function (err) {
          if (err) return promise.error(err);
          promise.complete(casted);
        });
      }));

      return this;
    };
count Casts this._conditions and sends a count command to mongodb. Invokes a callback upon receiving results ## param: Function callback fn(err, cardinality) api: public |
    Query.prototype.count = function (callback) {
      this.op = 'count';
      var model = this.model;

      try {
        this.cast(model);
      } catch (err) {
        return callback(err);
      }

      var castQuery = this._conditions;
      model.collection.count(castQuery, tick(callback));

      return this;
    };
distinct Casts this._conditions and sends a distinct command to mongodb. Invokes a callback upon receiving results ## param: Function callback fn(err, cardinality) api: public |
    Query.prototype.distinct = function (field, callback) {
      this.op = 'distinct';
      var model = this.model;

      try {
        this.cast(model);
      } catch (err) {
        return callback(err);
      }

      var castQuery = this._conditions;
      model.collection.distinct(field, castQuery, tick(callback));

      return this;
    };
update Casts the `doc` according to the model Schema and sends an update command to MongoDB. All paths passed that are not $atomic operations will become $set ops so we retain backwards compatibility. ## Example `Model.update({..}, { title: 'remove words' }, ...)` becomes `Model.update({..}, { $set: { title: 'remove words' }}, ...)` Passing an empty object `{}` as the doc will result in a no-op. The update operation will be ignored and the callback executed without sending the command to MongoDB so as to prevent accidently overwritting the collection. ## param: Object doc - the update param: Function callback - fn(err) api: public |
    Query.prototype.update = function update (doc, callback) {
      this.op = 'update';
      this._updateArg = doc;

      var model = this.model
        , options = this._optionsForExec(model)
        , fn = 'function' == typeof callback
        , castQuery
        , castDoc

      try {
        this.cast(model);
        castQuery = this._conditions;
      } catch (err) {
        if (fn) return callback(err);
        throw err;
      }

      try {
        castDoc = this._castUpdate(doc);
      } catch (err) {
        if (fn) return callback(err);
        throw err;
      }

      if (!fn) {
        delete options.safe;
      }

      if (castDoc) {
        model.collection.update(castQuery, castDoc, options, tick(callback));
      } else {
        process.nextTick(function () {
          callback(null, 0);
        });
      }

      return this;
    };
remove Casts the query, sends the remove command to mongodb where the query contents, and then invokes a callback upon receiving the command result. ## param: Function callback api: public |
    Query.prototype.remove = function (callback) {
      this.op = 'remove';

      var model = this.model
        , options = this._optionsForExec(model)
        , cb = 'function' == typeof callback

      try {
        this.cast(model);
      } catch (err) {
        if (cb) return callback(err);
        throw err;
      }

      if (!cb) {
        delete options.safe;
      }

      var castQuery = this._conditions;
      model.collection.remove(castQuery, options, tick(callback));
      return this;
    };
populate Sets population options. - api: public |
    Query.prototype.populate = function (path, fields, conditions, options) {
      // The order of fields/conditions args is opposite Model.find but
      // necessary to keep backward compatibility (fields could be
      // an array, string, or object literal).
      this.options.populate[path] =
        new PopulateOptions(fields, conditions, options);

      return this;
    };
stream Returns a stream interface ## Example
    Thing.find({ name: /^hello/ }).stream().pipe(res)
api: public |
    Query.prototype.stream = function stream () {
      return new QueryStream(this);
    }
Deprecated methods. |
    Query.prototype.$or = utils.dep('Query#$or', 'Query#or', Query.prototype.or);
    Query.prototype.$nor =utils.dep('Query#$nor', 'Query#nor', Query.prototype.nor);
    Query.prototype.run = utils.dep('Query#run', 'Query#exec', Query.prototype.exec);
    Query.prototype.$mod = utils.dep('Query#$mod', 'Query#mod', Query.prototype.mod);
    Query.prototype.$box = utils.dep('Query#$box', 'Query#box', Query.prototype.box);
    Query.prototype.$near = utils.dep('Query#$near', 'Query#near', Query.prototype.near);
    Query.prototype.$slice = utils.dep('Query#$slice', 'Query#slice', Query.prototype.slice);
    Query.prototype.notEqualTo = utils.dep('Query#notEqualTo', 'Query#ne', Query.prototype.ne);
    Query.prototype.fields = utils.dep('Query#fields', 'Query#select', Query.prototype.select);
    Query.prototype.$exists =utils.dep('Query#$exists', 'Query#exists', Query.prototype.exists);
    Query.prototype.$center = utils.dep('Query#$center', 'Query#center', Query.prototype.center);
    Query.prototype.$elemMatch =utils.dep('Query#$elemMatch', 'Query#elemMatch', Query.prototype.elemMatch);
    Query.prototype.$centerSphere = utils.dep('Query#$centerSphere', 'Query#centerSphere', Query.prototype.centerSphere);
asc Sorts ascending.
    query.asc('name', 'age');
deprecate: d |
    function asc () {
      var sort = this.options.sort || (this.options.sort = []);
      for (var i = 0, l = arguments.length; i &lt; l; i++) {
        sort.push([arguments[i], 1]);
      }
      return this;
    };
    Query.prototype.asc = utils.dep('Query#asc', 'Query#sort', asc);
desc Sorts descending.
    query.desc('name', 'age');
deprecate: d |
    function desc () {
      var sort = this.options.sort || (this.options.sort = []);
      for (var i = 0, l = arguments.length; i &lt; l; i++) {
        sort.push([arguments[i], -1]);
      }
      return this;
    };
    Query.prototype.desc = utils.dep('Query#desc', 'Query#sort', desc);
limit, skip, maxscan, snapshot, batchSize, comment Sets these associated options.
    query.comment('feed query');
deprecate: d |
    '$within wherein $wherein'.split(' ').forEach(function (getter) {
      var withinDep = utils.dep('Query#' + getter, 'Query#within')
      Object.defineProperty(Query.prototype, getter, {
        get: function () {
          withinDep();
          return this;
        }
      });
    });
only Chainable method for adding the specified fields to the object of fields to only include. ## Examples
    query.only('a b c');
    query.only('a', 'b', 'c');
    query.only(['a', 'b', 'c']);
## param: String | Array space separated list of fields OR an array of field names We can also take arguments as the "array" of field names api: public deprecate: d |
    function only (fields) {
      fields = this._parseOnlyExcludeFields.apply(this, arguments);
      this._applyFields({ only: fields });
      return this;
    };
    Query.prototype.only = utils.dep('Query#only', 'Query#select', only);
exclude Chainable method for adding the specified fields to the object of fields to exclude. ## Examples
    query.exclude('a b c');
    query.exclude('a', 'b', 'c');
    query.exclude(['a', 'b', 'c']);
## param: String | Array space separated list of fields OR an array of field names We can also take arguments as the "array" of field names api: public deprecate: d |
    function exclude (fields) {
      fields = this._parseOnlyExcludeFields.apply(this, arguments);
      this._applyFields({ exclude: fields });
      return this;
    };
    Query.prototype.exclude = utils.dep('Query#exclude', 'Query#select', exclude);
each() Streaming cursors. The `callback` is called repeatedly for each document found in the collection as it's streamed. If an error occurs streaming stops. ## Example
    query.each(function (err, user) {
      if (err) return res.end("aww, received an error. all done.");
      if (user) {
        res.write(user.name + '\n')
      } else {
        res.end("reached end of cursor. all done.");
      }
    });
A third parameter may also be used in the callback which allows you to iterate the cursor manually. ## Example
    query.each(function (err, user, next) {
      if (err) return res.end("aww, received an error. all done.");
      if (user) {
        res.write(user.name + '\n')
        doSomethingAsync(next);
      } else {
        res.end("reached end of cursor. all done.");
      }
    });
## param: Function callback return: Query deprecate: d api: public |
    function each (callback) {
      var model = this.model
        , options = this._optionsForExec(model)
        , manual = 3 == callback.length
        , self = this

      try {
        this.cast(model);
      } catch (err) {
        return callback(err);
      }

      var fields = utils.clone(options.fields = this._fields);

      function complete (err, val) {
        if (complete.ran) return;
        complete.ran = true;
        callback(err, val);
      }

      model.collection.find(this._conditions, options, function (err, cursor) {
        if (err) return complete(err);

        var ticks = 0;
        next();

        function next () {
          // nextTick is necessary to avoid stack overflows when
          // dealing with large result sets. yield occasionally.
          if (!(++ticks % 20)) {
            process.nextTick(function () {
              cursor.nextObject(onNextObject);
            });
          } else {
            cursor.nextObject(onNextObject);
          }
        }

        function onNextObject (err, doc) {
          if (err) return complete(err);

          // when doc is null we hit the end of the cursor
          if (!doc) return complete(null, null);

          var instance = new model(undefined, fields);

          // skip _id for pre-init hooks
          delete instance._doc._id;

          instance.init(doc, self, function (err) {
            if (err) return complete(err);

            if (manual) {
              callback(null, instance, next);
            } else {
              callback(null, instance);
              next();
            }
          });
        }

      });

      return this;
    }
    Query.prototype.each = utils.dep('Query#each', 'Query#stream', each);
Exports. |
    module.exports = Query;
    module.exports.QueryStream = QueryStream;
## array | lib/schema/array.js
Module dependencies. |
    var SchemaType = require('../schematype')
      , CastError = SchemaType.CastError
      , NumberSchema = require('./number')
      , Types = {
            Boolean: require('./boolean')
          , Date: require('./date')
          , Number: ArrayNumberSchema
          , String: require('./string')
          , ObjectId: require('./objectid')
          , Buffer: require('./buffer')
        }
      , MongooseArray = require('../types').Array
      , Mixed = require('./mixed')
      , Query = require('../query')
      , isMongooseObject = require('../utils').isMongooseObject
Inherits from SchemaType. |
    SchemaArray.prototype.__proto__ = SchemaType.prototype;
Module exports. |
    module.exports = SchemaArray;
## boolean | lib/schema/boolean.js
Module dependencies. |
    var SchemaType = require('../schematype');
Inherits from SchemaType. |
    SchemaBoolean.prototype.__proto__ = SchemaType.prototype;
Module exports. |
    module.exports = SchemaBoolean;
## buffer | lib/schema/buffer.js
Module dependencies. |
    var SchemaType = require('../schematype')
      , CastError = SchemaType.CastError
      , BufferNumberSchema = function () {}
      , MongooseBuffer = require('../types').Buffer
      , Binary = MongooseBuffer.Binary
      , Query = require('../query');
Inherits from SchemaType. |
    SchemaBuffer.prototype.__proto__ = SchemaType.prototype;
Module exports. |
    module.exports = SchemaBuffer;
## date | lib/schema/date.js
Module requirements. |
    var SchemaType = require('../schematype')
      , CastError = SchemaType.CastError;
Inherits from SchemaType. |
    SchemaDate.prototype.__proto__ = SchemaType.prototype;
Module exports. |
    module.exports = SchemaDate;
## documentarray | lib/schema/documentarray.js
Module dependencies. |
    var SchemaType = require('../schematype')
      , ArrayType = require('./array')
      , MongooseDocumentArray = require('../types/documentarray')
      , Subdocument = require('../types/embedded')
      , CastError = SchemaType.CastError
      , Document = require('../document');
Inherits from ArrayType. |
    DocumentArray.prototype.__proto__ = ArrayType.prototype;
Module exports. |
    module.exports = DocumentArray;
## index | lib/schema/index.js
Module exports. |
    exports.String = require('./string');

    exports.Number = require('./number');

    exports.Boolean = require('./boolean');

    exports.DocumentArray = require('./documentarray');

    exports.Array = require('./array');

    exports.Buffer = require('./buffer');

    exports.Date = require('./date');

    exports.ObjectId = require('./objectid');

    exports.Mixed = require('./mixed');
## mixed | lib/schema/mixed.js
Module dependencies. |
    var SchemaType = require('../schematype');
Inherits from SchemaType. |
    Mixed.prototype.__proto__ = SchemaType.prototype;
Module exports. |
    module.exports = Mixed;
## number | lib/schema/number.js
Module requirements. |
    var SchemaType = require('../schematype')
      , CastError = SchemaType.CastError
      , MongooseNumber = require('../types/number');
Inherits from SchemaType. |
    SchemaNumber.prototype.__proto__ = SchemaType.prototype;
Sets a maximum number validator ## param: Number minimum number api: public |
    SchemaNumber.prototype.min = function (value, message) {
      if (this.minValidator)
        this.validators = this.validators.filter(function(v){
          return v[1] != 'min';
        });
      if (value != null)
        this.validators.push([function(v){
          return v === null || v &gt;= value;
        }, 'min']);
      return this;
    };
Sets a maximum number validator ## param: Number maximum number api: public |
    SchemaNumber.prototype.max = function (value, message) {
      if (this.maxValidator)
        this.validators = this.validators.filter(function(v){
          return v[1] != 'max';
        });
      if (value != null)
        this.validators.push([this.maxValidator = function(v){
          return v === null || v &lt;= value;
        }, 'max']);
      return this;
    };
Module exports. |
    module.exports = SchemaNumber;
## objectid | lib/schema/objectid.js
Module dependencies. |
    var SchemaType = require('../schematype')
      , CastError = SchemaType.CastError
      , driver = global.MONGOOSE_DRIVER_PATH || './../drivers/node-mongodb-native'
      , oid = require('../types/objectid');
Inherits from SchemaType. |
    ObjectId.prototype.__proto__ = SchemaType.prototype;
Module exports. |
    module.exports = ObjectId;
## string | lib/schema/string.js
Module dependencies. |
    var SchemaType = require('../schematype')
      , CastError = SchemaType.CastError;
Inherits from SchemaType. |
    SchemaString.prototype.__proto__ = SchemaType.prototype;
Adds enumeration values ## param: multiple enumeration values api: public |
    SchemaString.prototype.enum = function () {
      var len = arguments.length;
      if (!len || undefined === arguments[0] || false === arguments[0]) {
        if (this.enumValidator){
          this.enumValidator = false;
          this.validators = this.validators.filter(function(v){
            return v[1] != 'enum';
          });
        }
        return;
      }

      for (var i = 0; i &lt; len; i++) {
        if (undefined !== arguments[i]) {
          this.enumValues.push(this.cast(arguments[i]));
        }
      }

      if (!this.enumValidator) {
        var values = this.enumValues;
        this.enumValidator = function(v){
          return ~values.indexOf(v);
        };
        this.validators.push([this.enumValidator, 'enum']);
      }
    };
Adds a lowercase setter api: public |
    SchemaString.prototype.lowercase = function () {
      return this.set(function (v) {
        return v.toLowerCase();
      });
    };
Adds an uppercase setter api: public |
    SchemaString.prototype.uppercase = function () {
      return this.set(function (v) {
        return v.toUpperCase();
      });
    };
Adds a trim setter api: public |
    SchemaString.prototype.trim = function () {
      return this.set(function (v) {
        return v.trim();
      });
    };
Sets a regexp test ## param: RegExp regular expression to test against param: String optional validator message api: public |
    SchemaString.prototype.match = function(regExp){
      this.validators.push([function(v){
        return regExp.test(v);
      }, 'regexp']);
    };
Module exports. |
    module.exports = SchemaString;
## schema | lib/schema.js
Module dependencies. |
    var EventEmitter = require('events').EventEmitter
      , VirtualType = require('./virtualtype')
      , utils = require('./utils')
      , NamedScope
      , Query
      , Types
Schema constructor. ## param: Object definition api: public |
    function Schema (obj, options) {
      this.paths = {};
      this.virtuals = {};
      this.nested = {};
      this.inherits = {};
      this.callQueue = [];
      this._indexes = [];
      this.methods = {};
      this.statics = {};
      this.tree = {};

      // set options
      this.options = utils.options({
          safe: true
        , strict: false
      }, options);

      // build paths
      if (obj)
        this.add(obj);

      if (!this.paths['_id'] &amp;&amp; !this.options.noId) {
        this.add({ _id: {type: ObjectId, auto: true} });
      }

      if (!this.paths['id'] &amp;&amp; !this.options.noVirtualId) {
        this.virtual('id').get(function () {
          if (this.__id) {
            return this.__id;
          }

          return this.__id = null == this._id
            ? null
            : this._id.toString();
        });
      }

      delete this.options.noVirtualId;
    };
Inherit from EventEmitter. |
    Schema.prototype.__proto__ = EventEmitter.prototype;
Sets the keys ## param: Object keys param: String prefix api: public |
    Schema.prototype.add = function add (obj, prefix) {
      prefix = prefix || '';
      for (var i in obj) {
        if (null == obj[i]) {
          throw new TypeError('Invalid value for schema path `'+ prefix + i +'`');
        }

        if (obj[i].constructor.name == 'Object' &amp;&amp; (!obj[i].type || obj[i].type.type)) {
          if (Object.keys(obj[i]).length) {
            // nested object { last: { name: String }}
            this.nested[prefix + i] = true;
            this.add(obj[i], prefix + i + '.');
          }
          else
            this.path(prefix + i, obj[i]); // mixed type
        } else
          this.path(prefix + i, obj[i]);
      }
    };
Sets a path (if arity 2) Gets a path (if arity 1) ## param: String path param: Object constructor api: public |
    Schema.prototype.path = function (path, obj) {
      if (obj == undefined) {
        if (this.paths[path]) return this.paths[path];

        // Sometimes path will come in as
        // pathNameA.4.pathNameB where 4 means the index
        // of an embedded document in an embedded array.
        // In this case, we need to jump to the Array's
        // schema and call path() from there to resolve to
        // the correct path type

        var last
          , self = this
          , subpaths = path.split(/\.(\d+)\.?/)
                           .filter(Boolean) // removes empty strings

        if (subpaths.length &gt; 1) {
          last = subpaths.length - 1;
          return subpaths.reduce(function (val, subpath, i) {
            if (val &amp;&amp; !val.schema) {
              if (i === last &amp;&amp; !/\D/.test(subpath) &amp;&amp; val instanceof Types.Array) {
                return val.caster; // StringSchema, NumberSchema, etc
              } else {
                return val;
              }
            }

            if (!/\D/.test(subpath)) { // 'path.0.subpath'  on path 0
              return val;
            }

            return val ? val.schema.path(subpath)
                       : self.path(subpath);
          }, null);
        }

        return this.paths[subpaths[0]];
      }

      // update the tree
      var subpaths = path.split(/\./)
        , last = subpaths.pop()
        , branch = this.tree;

      subpaths.forEach(function(path) {
        if (!branch[path]) branch[path] = {};
        branch = branch[path];
      });

      branch[last] = utils.clone(obj);

      this.paths[path] = Schema.interpretAsType(path, obj);
      return this;
    };
Converts -- e.g., Number, [SomeSchema], { type: String, enum: ['m', 'f'] } -- into the appropriate Mongoose Type, which we use later for casting, validation, etc. ## param: String path param: Object constructor |
    Schema.interpretAsType = function (path, obj) {
      if (obj.constructor.name != 'Object')
        obj = { type: obj };

      // Get the type making sure to allow keys named "type"
      // and default to mixed if not specified.
      // { type: { type: String, default: 'freshcut' } }
      var type = obj.type &amp;&amp; !obj.type.type
        ? obj.type
        : {};

      if (type.constructor.name == 'Object') {
        return new Types.Mixed(path, obj);
      }

      if (Array.isArray(type) || type == Array) {
        // if it was specified through { type } look for `cast`
        var cast = type == Array
          ? obj.cast
          : type[0];

        if (cast instanceof Schema) {
          return new Types.DocumentArray(path, cast, obj);
        }

        return new Types.Array(path, cast || Types.Mixed, obj);
      }

      if (undefined == Types[type.name]) {
        throw new TypeError('Undefined type at `' + path +
            '`\n  Did you try nesting Schemas? ' +
            'You can only nest using refs or arrays.');
      }

      return new Types[type.name](path, obj);
    };
Iterates through the schema's paths, passing the path string and type object to the callback. ## param: Function callback function - fn(pathstring, type) return: Schema this for chaining api: public |
    Schema.prototype.eachPath = function (fn) {
      var keys = Object.keys(this.paths)
        , len = keys.length;

      for (var i = 0; i &lt; len; ++i) {
        fn(keys[i], this.paths[keys[i]]);
      }

      return this;
    };
Returns an Array of path strings that are required. - api: public |
    Object.defineProperty(Schema.prototype, 'requiredPaths', {
      get: function () {
        var paths = this.paths
          , pathnames = Object.keys(paths)
          , i = pathnames.length
          , pathname, path
          , requiredPaths = [];
        while (i--) {
          pathname = pathnames[i];
          path = paths[pathname];
          if (path.isRequired) requiredPaths.push(pathname);
        }
        return requiredPaths;
      }
    });
Given a path, returns whether it is a real, virtual, nested, or ad-hoc/undefined path. ## param: String path return: String api: public |
    Schema.prototype.pathType = function (path) {
      if (path in this.paths) return 'real';
      if (path in this.virtuals) return 'virtual';
      if (path in this.nested) return 'nested';
      return 'adhocOrUndefined';
    };
Defines a pre for the document ## param: String method param: Function callback api: public |
    Schema.prototype.pre = function(){
      return this.queue('pre', arguments);
    };
Defines a post for the document ## param: String method param: Function callback api: public |
    Schema.prototype.post = function(method, fn){
      return this.queue('on', arguments);
    };
Registers a plugin for this schema ## param: Function plugin callback api: public |
    Schema.prototype.plugin = function (fn, opts) {
      fn(this, opts);
      return this;
    };
Adds a method ## param: String method name param: Function handler api: public |
    Schema.prototype.method = function (name, fn) {
      if ('string' != typeof name)
        for (var i in name)
          this.methods[i] = name[i];
      else
        this.methods[name] = fn;
      return this;
    };
Defines a static method ## param: String name param: Function handler api: public |
    Schema.prototype.static = function(name, fn) {
      if ('string' != typeof name)
        for (var i in name)
          this.statics[i] = name[i];
      else
        this.statics[name] = fn;
      return this;
    };
Defines an index (most likely compound) ## Example schema.index({ first: 1, last: -1 }) ## param: Object field param: Object optional options object api: public |
    Schema.prototype.index = function (fields, options) {
      this._indexes.push([fields, options || {}]);
      return this;
    };
Sets/gets an option ## param: String key param: Object optional value api: public |
    Schema.prototype.set = function (key, value) {
      if (arguments.length == 1)
        return this.options[key];
      this.options[key] = value;
      return this;
    };
Compiles indexes from fields and schema-level indexes api: public |
    Schema.prototype.__defineGetter__('indexes', function () {
      var indexes = []
        , seenSchemas = [];

      collectIndexes(this);

      return indexes;

      function collectIndexes (schema, prefix) {
        if (~seenSchemas.indexOf(schema)) return;
        seenSchemas.push(schema);

        var index;
        var paths = schema.paths;
        prefix = prefix || '';

        for (var i in paths) {
          if (paths[i]) {
            if (paths[i] instanceof Types.DocumentArray) {
              collectIndexes(paths[i].schema, i + '.');
            } else {
              index = paths[i]._index;

              if (index !== false &amp;&amp; index !== null){
                var field = {};
                field[prefix + i] = '2d' === index ? index : 1;
                indexes.push([field, 'Object' === index.constructor.name ? index : {} ]);
              }
            }
          }
        }

        if (prefix) {
          fixSubIndexPaths(schema, prefix);
        } else {
          indexes = indexes.concat(schema._indexes);
        }
      }
Checks for indexes added to subdocs using Schema.index(). These indexes need their paths prefixed properly. schema._indexes = [ [indexObj, options], [indexObj, options] ..] |
    function fixSubIndexPaths (schema, prefix) {
        var subindexes = schema._indexes
          , len = subindexes.length
          , indexObj
          , newindex
          , klen
          , keys
          , key
          , i = 0
          , j

        for (i = 0; i &lt; len; ++i) {
          indexObj = subindexes[i][0];
          keys = Object.keys(indexObj);
          klen = keys.length;
          newindex = {};

          // use forward iteration, order matters
          for (j = 0; j &lt; klen; ++j) {
            key = keys[j];
            newindex[prefix + key] = indexObj[key];
          }

          indexes.push([newindex, subindexes[i][1]]);
        }
      }

    });
Retrieves or creates the virtual type with the given name. ## param: String name return: VirtualType |
    Schema.prototype.virtual = function (name, options) {
      var virtuals = this.virtuals || (this.virtuals = {});
      var parts = name.split('.');
      return virtuals[name] = parts.reduce(function (mem, part, i) {
        mem[part] || (mem[part] = (i === parts.length-1)
                                ? new VirtualType(options)
                                : {});
        return mem[part];
      }, this.tree);
    };
Fetches the virtual type with the given name. Should be distinct from virtual because virtual auto-defines a new VirtualType if the path doesn't exist. ## param: String name return: VirtualType |
    Schema.prototype.virtualpath = function (name) {
      return this.virtuals[name];
    };

    Schema.prototype.namedScope = function (name, fn) {
      var namedScopes = this.namedScopes || (this.namedScopes = new NamedScope)
        , newScope = Object.create(namedScopes)
        , allScopes = namedScopes.scopesByName || (namedScopes.scopesByName = {});
      allScopes[name] = newScope;
      newScope.name = name;
      newScope.block = fn;
      newScope.query = new Query();
      newScope.decorate(namedScopes, {
        block0: function (block) {
          return function () {
            block.call(this.query);
            return this;
          };
        },
        blockN: function (block) {
          return function () {
            block.apply(this.query, arguments);
            return this;
          };
        },
        basic: function (query) {
          return function () {
            this.query.find(query);
            return this;
          };
        }
      });
      return newScope;
    };
ObjectId schema identifier. Not an actual ObjectId, only used for Schemas. api: public |
    function ObjectId () {
      throw new Error('This is an abstract interface. Its only purpose is to mark '
                    + 'fields as ObjectId in the schema creation.');
    }
Module exports. |
    module.exports = exports = Schema;

    // require down here because of reference issues
    exports.Types = Types = require('./schema/index');
    NamedScope = require('./namedscope')
    Query = require('./query');

    exports.ObjectId = ObjectId;
## schemadefault | lib/schemadefault.js
Module dependencies. |
    var Schema = require('./schema')
Default model for querying the system.profiles collection (it only exists when profiling is enabled. |
    exports['system.profile'] = new Schema({
        ts: Date
      , info: String // deprecated
      , millis: Number
      , op: String
      , ns: String
      , query: Schema.Types.Mixed
      , updateobj: Schema.Types.Mixed
      , ntoreturn: Number
      , nreturned: Number
      , nscanned: Number
      , responseLength: Number
      , client: String
      , user: String
      , idhack: Boolean
      , scanAndOrder: Boolean
      , keyUpdates: Number
      , cursorid: Number
    }, { noVirtualId: true, noId: true });
## schematype | lib/schematype.js
Module dependencies. |
    var MongooseError = require('./error');
    var utils = require('./utils');
SchemaType constructor ## param: String path api: public |
    function SchemaType (path, options, instance) {
      this.path = path;
      this.instance = instance;
      this.validators = [];
      this.setters = [];
      this.getters = [];
      this.options = options;
      this._index = null;
      this.selected;

      for (var i in options) if (this[i] &amp;&amp; 'function' == typeof this[i]) {
        var opts = Array.isArray(options[i])
          ? options[i]
          : [options[i]];

        this[i].apply(this, opts);
      }
    };
Sets a default ## param: Object default value api: public |
    SchemaType.prototype.default = function (val) {
      if (1 === arguments.length) {
        this.defaultValue = typeof val === 'function'
          ? val
          : this.cast(val);
        return this;
      } else if (arguments.length &gt; 1) {
        this.defaultValue = utils.args(arguments);
      }
      return this.defaultValue;
    };
Sets index. It can be a boolean or a hash of options ## Example Schema.path('my.path').index(true); Schema.path('my.path').index({ unique: true }); "Direction doesn't matter for single key indexes" http://www.mongodb.org/display/DOCS/Indexes#Indexes-CompoundKeysIndexes ## param: Object true/ api: public |
    SchemaType.prototype.index = function (index) {
      this._index = index;
      return this;
    };
Adds a setter ## param: Function setter api: public |
    SchemaType.prototype.set = function (fn) {
      if ('function' != typeof fn)
        throw new Error('A setter must be a function.');
      this.setters.push(fn);
      return this;
    };
Adds a getter ## param: Function getter api: public |
    SchemaType.prototype.get = function (fn) {
      if ('function' != typeof fn)
        throw new Error('A getter must be a function.');
      this.getters.push(fn);
      return this;
    };
## validate Adds validators. ## Examples
    function validator () { ... }

    var single = [validator, 'failed']
    new Schema({ name: { type: String, validate: single }});

    var many = [
        { validator: validator, msg: 'uh oh' }
      , { validator: fn, msg: 'failed' }
    ]
    new Schema({ name: { type: String, validate: many }});
## param: Object validator param: String optional error message api: public |
    SchemaType.prototype.validate = function (obj, error) {
      if ('function' == typeof obj || obj &amp;&amp; 'RegExp' === obj.constructor.name) {
        this.validators.push([obj, error]);
        return this;
      }

      var i = arguments.length
        , arg

      while (i--) {
        arg = arguments[i];
        this.validators.push([arg.validator, arg.msg]);
      }

      return this;
    };
Adds a required validator ## param: Boolean enable/disable the validator api: public |
    SchemaType.prototype.required = function (required) {
      var self = this;

      function __checkRequired (v) {
        // in here, `this` refers to the validating document.
        // no validation when this path wasn't selected in the query.
        if ('isSelected' in this &amp;&amp;
            !this.isSelected(self.path) &amp;&amp;
            !this.isModified(self.path)) return true;
        return self.checkRequired(v);
      }

      if (false === required) {
        this.isRequired = false;
        this.validators = this.validators.filter(function (v) {
          return v[0].name !== '__checkRequired';
        });
      } else {
        this.isRequired = true;
        this.validators.push([__checkRequired, 'required']);
      }

      return this;
    };
## select Set default select() behavior for this path. True if this path should always be included in the results, false if it should be excluded by default. This setting can be overridden at the query level.
    T = db.model('T', new Schema({ x: { type: String, select: true }}));
    T.find(..); // x will always be selected ..
    // .. unless overridden;
    T.find().select({ x: 0 }).exec();
    SchemaType.prototype.select = function select (val) {
      this.selected = !! val;
    }
Inherits from MongooseError |
    ValidatorError.prototype.__proto__ = MongooseError.prototype;
Inherits from MongooseError. |
    CastError.prototype.__proto__ = MongooseError.prototype;
Module exports. |
    module.exports = exports = SchemaType;

    exports.CastError = CastError;

    exports.ValidatorError = ValidatorError;
## statemachine | lib/statemachine.js
Module dependencies. |
    var utils = require('./utils');
## array | lib/types/array.js
Module dependencies. |
    var EmbeddedDocument = require('./embedded');
    var Document = require('../document');
    var ObjectId = require('./objectid');
    var utils = require('../utils')
Inherit from Array |
    MongooseArray.prototype = new Array;
Marks this array as modified. It is called during a nonAtomicPush, an atomic opteration, or by an existing embedded document that is modified. If it bubbles up from an embedded document change, then it takes the following arguments (otherwise, takes 0 arguments) ## param: EmbeddedDocument embeddedDoc that invokes this method on the Array param: String embeddedPath is what changed inthe embeddedDoc api: public |
    MongooseArray.prototype._markModified = function (embeddedDoc, embeddedPath) {
      var parent = this._parent
        , dirtyPath;

      if (parent) {
        if (arguments.length) {
          // If an embedded doc bubbled up the change
          dirtyPath = [this._path, this.indexOf(embeddedDoc), embeddedPath].join('.');
        } else {
          dirtyPath = this._path;
        }
        parent.markModified(dirtyPath);
      }

      return this;
    };
Returns true if we have to perform atomics for this, and no normal operations api: public |
    MongooseArray.prototype.__defineGetter__('doAtomics', function () {
      if (!(this._atomics &amp;&amp; 'Object' === this._atomics.constructor.name)) {
        return 0;
      }

      return Object.keys(this._atomics).length;
    });
Pushes item/s to the array atomically. Overrides Array#push ## param: Object value api: public |
    MongooseArray.prototype.push = function () {
      var values = [].map.call(arguments, this._cast, this)
        , ret = [].push.apply(this, values);

      // $pushAll might be fibbed (could be $push). But it makes it easier to
      // handle what could have been $push, $pushAll combos
      this._registerAtomic('$pushAll', values);
      return ret;
    };
    MongooseArray.prototype.$push =
      utils.dep('MongooseArray#$push'
              , 'MongooseArray#push', MongooseArray.prototype.push);
Pushes item/s to the array non-atomically ## param: Object value api: public |
    MongooseArray.prototype.nonAtomicPush = function () {
      var values = [].map.call(arguments, this._cast, this)
        , ret = [].push.apply(this, values);
      this._markModified();
      return ret;
    };
Pushes several items at once to the array atomically ## param: Array values api: public deprecate: d |
    function $pushAll (value) {
      var length = this.length;
      this.nonAtomicPush.apply(this, value);
      // make sure we access the casted elements
      this._registerAtomic('$pushAll', this.slice(length));
      return this;
    };
    MongooseArray.prototype.$pushAll =
      utils.dep('MongooseArray#$pushAll'
              , 'MongooseArray#push in v3', $pushAll);
Pops the array atomically api: public |
    MongooseArray.prototype.pop =
    MongooseArray.prototype.$pop = function () {
      this._registerAtomic('$pop', 1);
      return [].pop.call(this)
    };
Atomically shifts the array. Only works once per doc.save(). Calling this mulitple times on an array before saving is the same as calling it once. api: public |
    MongooseArray.prototype.shift =
    MongooseArray.prototype.$shift = function $shift () {
      this._registerAtomic('$pop', -1);
      return [].shift.call(this)
    };
Removes items from an array atomically ## Examples
    doc.array.remove(ObjectId)
    doc.array.remove('tag 1', 'tag 2')
## param: Object value to remove api: public |
    MongooseArray.prototype.remove = function () {
      var args = [].map.call(arguments, this._cast, this);
      if (args.length == 1)
        this.$pull(args[0]);
      else
        this.$pullAll(args);
      return args;
    };
Pulls from the array api: public |
    MongooseArray.prototype.pull = function () {
      var values = [].map.call(arguments, this._cast, this)
        , cur = this._parent.get(this._path)
        , i = cur.length
        , mem;

      while (i--) {
        mem = cur[i];
        if (mem instanceof EmbeddedDocument) {
          if (values.some(function (v) { return v.equals(mem); } )) {
            [].splice.call(cur, i, 1);
          }
        } else if (~cur.indexOf.call(values, mem)) {
          [].splice.call(cur, i, 1);
        }
      }

      if (values[0] instanceof EmbeddedDocument) {
        this._registerAtomic('$pullDocs', values.map( function (v) { return v._id; } ));
      } else {
        this._registerAtomic('$pullAll', values);
      }

      return this;
    };
    MongooseArray.prototype.$pull =
      utils.dep('MongooseArray#$pull'
              , 'MongooseArray#pull', MongooseArray.prototype.pull);
Pulls many items from an array api: public deprecate: d |
    function $pullAll (values) {
      if (values &amp;&amp; values.length) {
        var oldArr = this._parent.get(this._path)
          , i = oldArr.length, mem;
        while (i--) {
          mem = oldArr[i];
          if (mem instanceof EmbeddedDocument) {
            if (values.some( function (v) { return v.equals(mem); } )) {
              oldArr.splice(i, 1);
            }
          } else if (~values.indexOf(mem)) oldArr.splice(i, 1);
        }
        if (values[0] instanceof EmbeddedDocument) {
          this._registerAtomic('$pullDocs', values.map( function (v) { return v._id; } ));
        } else {
          this._registerAtomic('$pullAll', values);
        }
      }
      return this;
    };
    MongooseArray.prototype.$pullAll =
      utils.dep('MongooseArray#$pullAll', 'MongooseArray#pull', $pullAll);
Splices the array. ## Note marks the _entire_ array as modified which will pass the entire thing to $set potentially overwritting any changes that happen between when you retrieved the object and when you save it. api: public |
    MongooseArray.prototype.splice = function () {
      var result = [].splice.apply(this, arguments);
      this._markModified();
      return result;
    };
Non-atomically unshifts onto the array. ## Note marks the _entire_ array as modified which will pass the entire thing to $set potentially overwritting any changes that happen between when you retrieved the object and when you save it. api: public |
    MongooseArray.prototype.unshift = function () {
      var values = [].map.call(arguments, this._cast, this);
      [].unshift.apply(this, values);
      this._markModified();
      return this.length;
    };
    MongooseArray.prototype.$unshift =
      utils.dep('MongooseArray#$unshift'
              , 'MongooseArray#unshift', MongooseArray.prototype.unshift);
Adds values to the array if not already present. - api: public |
    MongooseArray.prototype.addToSet = function addToSet () {
      var values = [].map.call(arguments, this._cast, this)
        , added = []
        , type = values[0] instanceof EmbeddedDocument ? 'doc' :
                 values[0] instanceof Date ? 'date' :
                 '';

      values.forEach(function (v) {
        var found;
        switch (type) {
          case 'doc':
            found = this.some(function(doc){ return doc.equals(v) });
            break;
          case 'date':
            var val = +v;
            found = this.some(function(d){ return +d === val });
            break;
          default:
            found = ~this.indexOf(v);
        }

        if (!found) {
          [].push.call(this, v);
          this._registerAtomic('$addToSet', v);
          [].push.call(added, v);
        }
      }, this);

      return added;
    };
    MongooseArray.prototype.$addToSet =
      utils.dep('MongooseArray#$addToSet'
              , 'MongooseArray#addToSet', MongooseArray.prototype.addToSet);
Returns an Array ## return: Array api: public |
    MongooseArray.prototype.toObject = function (options) {
      if (options &amp;&amp; options.depopulate &amp;&amp; this[0] instanceof Document) {
        return this.map(function (doc) {
          return doc._id;
        });
      }

      return this.map(function (doc) {
        return doc;
      });
    };
Helper for console.log api: public |
    MongooseArray.prototype.inspect = function () {
      return '[' + this.map(function (doc) {
        return ' ' + doc;
      }) + ' ]';
    };
Return the index of `obj` or `-1.` ## param: Object obj return: Number api: public |
    MongooseArray.prototype.indexOf = function indexOf (obj) {
      if (obj instanceof ObjectId) obj = obj.toString();
      for (var i = 0, len = this.length; i &lt; len; ++i) {
        if (obj == this[i])
          return i;
      }
      return -1;
    };
Module exports. |
    module.exports = exports = MongooseArray;
## buffer | lib/types/buffer.js
Access driver. |
    var driver = global.MONGOOSE_DRIVER_PATH || '../drivers/node-mongodb-native';
Module dependencies. |
    var Binary = require(driver + '/binary');
Inherit from Buffer. |
    MongooseBuffer.prototype = new Buffer(0);
Marks this buffer as modified. api: public |
    MongooseBuffer.prototype._markModified = function () {
      var parent = this._parent;

      if (parent) {
        parent.markModified(this._path);
      }
      return this;
    };
Writes the buffer. |
    MongooseBuffer.prototype.write = function () {
      var written = Buffer.prototype.write.apply(this, arguments);

      if (written &gt; 0) {
        this._markModified();
      }

      return written;
    };
Copy the buffer. ## Note Buffer#copy will not mark target as modified so you must copy from a MongooseBuffer for it to work as expected. Work around since copy modifies the target, not this. |
    MongooseBuffer.prototype.copy = function (target) {
      var ret = Buffer.prototype.copy.apply(this, arguments);

      if (target instanceof MongooseBuffer) {
        target._markModified();
      }

      return ret;
    };
Compile other Buffer methods marking this buffer as modified. |
    ;(
    // node < 0.5
    'writeUInt8 writeUInt16 writeUInt32 writeInt8 writeInt16 writeInt32 ' +
    'writeFloat writeDouble fill ' +
    'utf8Write binaryWrite asciiWrite set ' +

    // node >= 0.5
    'writeUInt16LE writeUInt16BE writeUInt32LE writeUInt32BE ' +
    'writeInt16LE writeInt16BE writeInt32LE writeInt32BE ' +
    'writeFloatLE writeFloatBE writeDoubleLE writeDoubleBE'
    ).split(' ').forEach(function (method) {
      if (!Buffer.prototype[method]) return;
      MongooseBuffer.prototype[method] = new Function(
        'var ret = Buffer.prototype.'+method+'.apply(this, arguments);' +
        'this._markModified();' +
        'return ret;'
      )
    });
Returns a Binary. ## return: Buffer api: public |
    MongooseBuffer.prototype.toObject = function () {
      return new Binary(this, x00);
    };
Module exports. |
    MongooseBuffer.Binary = Binary;

    module.exports = MongooseBuffer;
## document | lib/types/document.js
Module dependencies. |
    var Document = require('../document')
      , inspect = require('util').inspect;
Inherit from Document |
    EmbeddedDocument.prototype.__proto__ = Document.prototype;
Override set to mark the parent as modified api: public |
    var oldSet = Document.prototype.set;

    EmbeddedDocument.prototype.set = function (path) {
      this.markModified(path);
      return oldSet.apply(this, arguments);
    };
Save the subdocument api: public |
    EmbeddedDocument.prototype.save = function(fn) {
      if (fn)
        fn(null);
      this.emit('save', this);
      return this;
    };
Remove the subdocument api: public |
    EmbeddedDocument.prototype.remove = function (fn) {
      var _id;
      if (!this.willRemove) {
        _id = this._doc._id;
        if (!_id) {
          throw new Error('For your own good, Mongoose does not know ' +
                          'how to remove an EmbeddedDocument that has no _id');
        }
        this.parentArray.$pull({ _id: _id });
        this.willRemove = true;
      }

      if (fn)
        fn(null);

      return this;
    };
Helper for console.log api: public |
    EmbeddedDocument.prototype.inspect = function () {
      return inspect(this.toObject());
    };
Module exxports. |
    module.exports = EmbeddedDocument;
## documentarray | lib/types/documentarray.js
Module dependencies. |
    var MongooseArray = require('./array')
      , driver = global.MONGOOSE_DRIVER_PATH || '../drivers/node-mongodb-native'
      , ObjectId = require(driver + '/objectid')
      , ObjectIdSchema = require('../schema/objectid');
Inherits from MongooseArray |
    MongooseDocumentArray.prototype.__proto__ = MongooseArray.prototype;
Filters items by id ## param: Object id api: public |
    MongooseDocumentArray.prototype.id = function (id) {
      var casted
        , _id;

      try {
        casted = ObjectId.toString(ObjectIdSchema.prototype.cast.call({}, id));
      } catch (e) {
        casted = null;
      }

      for (var i = 0, l = this.length; i &lt; l; i++) {
        _id = this[i].get('_id');
        if (!(_id instanceof ObjectId)) {
          if (String(id) == _id)
            return this[i];
        } else {
          if (casted == _id)
            return this[i];
        }
      }

      return null;
    };
Returns an Array and converts any Document members toObject. ## return: Array api: public |
    MongooseDocumentArray.prototype.toObject = function () {
      return this.map(function (doc) {
        return doc &amp;&amp; doc.toObject() || null;
      });
    };
Helper for console.log api: public |
    MongooseDocumentArray.prototype.inspect = function () {
      return '[' + this.map(function (doc) {
        return doc &amp;&amp; doc.inspect() || 'null';
      }).join('\n') + ']';
    };
Module exports. |
    module.exports = MongooseDocumentArray;
## embedded | lib/types/embedded.js
Module dependencies. |
    var Document = require('../document')
      , inspect = require('util').inspect;
Inherit from Document |
    EmbeddedDocument.prototype.__proto__ = Document.prototype;
Noop. Does not actually save the doc to the db. api: public |
    EmbeddedDocument.prototype.save = function(fn) {
      if (fn)
        fn(null);
      return this;
    };
Remove the subdocument api: public |
    EmbeddedDocument.prototype.remove = function (fn) {
      var _id;
      if (!this.willRemove) {
        _id = this._doc._id;
        if (!_id) {
          throw new Error('For your own good, Mongoose does not know ' +
                          'how to remove an EmbeddedDocument that has no _id');
        }
        this.parentArray.$pull({ _id: _id });
        this.willRemove = true;
      }

      if (fn)
        fn(null);

      return this;
    };
Helper for console.log api: public |
    EmbeddedDocument.prototype.inspect = function () {
      return inspect(this.toObject());
    };
Module exports. |
    module.exports = EmbeddedDocument;
## index | lib/types/index.js
Module exports. |
    exports.Array = require('./array');
    exports.Buffer = require('./buffer');

    exports.Document = // @deprecate
    exports.Embedded = require('./embedded');

    exports.DocumentArray = require('./documentarray');
    exports.Number = require('./number');
    exports.ObjectId = require('./objectid');
## number | lib/types/number.js
Module dependencies. |
    var utils = require('./../utils')
Inherits from Number. |
    MongooseNumber.prototype = new Number();

    var depInc = utils.dep('MongooseNumber#$inc / MongooseNumber#increment', 'Model.update() to get incrementation in v3');
    var depDec = utils.dep('MongooseNumber#decrement', 'Model.update() to get decrementation in v3');
Atomic increment api: public |
    function increment (value) {
      depInc();
      var schema = this._parent.schema.path(this._path)
        , value = Number(value) || 1;
      if (isNaN(value)) value = 1;
      this._parent.setValue(this._path, schema.cast(this + value));
      this._parent.getValue(this._path)._atomics['$inc'] = value || 1;
      this._parent._activePaths.modify(this._path);
      return this;
    };
    MongooseNumber.prototype.$inc =
    MongooseNumber.prototype.increment = increment;
Returns true if we have to perform atomics for this, and no normal operations api: public |
    MongooseNumber.prototype.__defineGetter__('doAtomics', function () {
      return Object.keys(this._atomics).length;
    });
Atomic decrement api: public |
    MongooseNumber.prototype.decrement = function(){
      depDec();
      this.increment(-1);
    };
Re-declare toString (for `console.log`) api: public |
    MongooseNumber.prototype.inspect =
    MongooseNumber.prototype.toString = function () {
      return String(this.valueOf());
    };
Module exports |
    module.exports = MongooseNumber;
## objectid | lib/types/objectid.js
Access driver. |
    var driver = global.MONGOOSE_DRIVER_PATH || '../drivers/node-mongodb-native';
Module exports. |
    module.exports = require(driver + '/objectid');
## utils | lib/utils.js
Module dependencies. |
    var EventEmitter = require('events').EventEmitter
      , ObjectId = require('./types/objectid')
      , MongooseBuffer
      , MongooseArray
      , Document
Pluralization rules. |
    var rules = [
      [/(m)an$/gi, '$1en'],
      [/(pe)rson$/gi, '$1ople'],
      [/(child)$/gi, '$1ren'],
      [/^(ox)$/gi, '$1en'],
      [/(ax|test)is$/gi, '$1es'],
      [/(octop|vir)us$/gi, '$1i'],
      [/(alias|status)$/gi, '$1es'],
      [/(bu)s$/gi, '$1ses'],
      [/(buffal|tomat|potat)o$/gi, '$1oes'],
      [/([ti])um$/gi, '$1a'],
      [/sis$/gi, 'ses'],
      [/(?:([^f])fe|([lr])f)$/gi, '$1$2ves'],
      [/(hive)$/gi, '$1s'],
      [/([^aeiouy]|qu)y$/gi, '$1ies'],
      [/(x|ch|ss|sh)$/gi, '$1es'],
      [/(matr|vert|ind)ix|ex$/gi, '$1ices'],
      [/([m|l])ouse$/gi, '$1ice'],
      [/(quiz)$/gi, '$1zes'],
      [/s$/gi, 's'],
      [/$/gi, 's']
    ];
Uncountable words. |
    var uncountables = [
      'advice',
      'energy',
      'excretion',
      'digestion',
      'cooperation',
      'health',
      'justice',
      'labour',
      'machinery',
      'equipment',
      'information',
      'pollution',
      'sewage',
      'paper',
      'money',
      'species',
      'series',
      'rain',
      'rice',
      'fish',
      'sheep',
      'moose',
      'deer',
      'news'
    ];
Inherit from EventEmitter. |
    Events.prototype.__proto__ = EventEmitter.prototype;
Add `once`. |
    Events.prototype.once = function (type, listener) {
        var self = this;
        self.on(type, function g(){
          self.removeListener(type, g);
          listener.apply(this, arguments);
        });
      };

    }

    exports.EventEmitter = Events;

    // Modified from node/lib/assert.js
    exports.deepEqual = function deepEqual (a, b) {
      if (a === b) return true;

      if (a instanceof Date &amp;&amp; b instanceof Date)
        return a.getTime() === b.getTime();

      if (a instanceof ObjectId &amp;&amp; b instanceof ObjectId) {
        return a.toString() === b.toString();
      }

      if (typeof a !== 'object' &amp;&amp; typeof b !== 'object')
        return a == b;

      if (a === null || b === null || a === undefined || b === undefined)
        return false

      if (a.prototype !== b.prototype) return false;

      // Handle MongooseNumbers
      if (a instanceof Number &amp;&amp; b instanceof Number) {
        return a.valueOf() === b.valueOf();
      }

      if (Buffer.isBuffer(a)) {
        if (!Buffer.isBuffer(b)) return false;
        if (a.length !== b.length) return false;
        for (var i = 0, len = a.length; i &lt; len; ++i) {
          if (a[i] !== b[i]) return false;
        }
        return true;
      }

      if (isMongooseObject(a)) a = a.toObject();
      if (isMongooseObject(b)) b = b.toObject();

      try {
        var ka = Object.keys(a),
            kb = Object.keys(b),
            key, i;
      } catch (e) {//happens when one is a string literal and the other isn't
        return false;
      }

      // having the same number of owned properties (keys incorporates
      // hasOwnProperty)
      if (ka.length != kb.length)
        return false;

      //the same set of keys (although not necessarily the same order),
      ka.sort();
      kb.sort();

      //~~~cheap key test
      for (i = ka.length - 1; i &gt;= 0; i--) {
        if (ka[i] != kb[i])
          return false;
      }

      //equivalent values for every corresponding key, and
      //~~~possibly expensive deep test
      for (i = ka.length - 1; i &gt;= 0; i--) {
        key = ka[i];
        if (!deepEqual(a[key], b[key])) return false;
      }

      return true;
    };
Merges `from` into `to` without overwriting existing properties of `to`. ## param: Object to param: Object from |
    exports.merge = function merge (to, from) {
      var keys = Object.keys(from)
        , i = keys.length
        , key

      while (i--) {
        key = keys[i];
        if ('undefined' === typeof to[key]) {
          to[key] = from[key];
        } else {
          merge(to[key], from[key]);
        }
      }
    };
A faster Array.prototype.slice.call(arguments) alternative |
    exports.args = function (args, slice, sliceEnd) {
      var ret = [];
      var start = slice || 0;
      var end = 3 === arguments.length
        ? sliceEnd
        : args.length;

      for (var i = start; i &lt; end; ++i) {
        ret[i - start] = args[i];
      }

      return ret;
    }
Returns if `v` is a mongoose object that has a `toObject()` method we can use. This is for compatibility with libs like Date.js which do foolish things to Natives. |
    var isMongooseObject = exports.isMongooseObject = function (v) {
      Document || (Document = require('./document'));
      MongooseArray || (MongooseArray = require('./types').Array);
      MongooseBuffer || (MongooseBuffer = require('./types').Buffer);

      return v instanceof Document ||
             v instanceof MongooseArray ||
             v instanceof MongooseBuffer
    }
API deprecation helper. Disable deprecation warnings by setting the MONGOOSEDEPWARNINGS environment variable to false, or mongoose.set('dep warnings', false); |
    var warn =false;
    ;(exports.dep = function deprecate (old, rec, fn, scope) {
      return function () {
        if (warn &amp;&amp; !exports.dep.cache[old])  {
          exports.dep.cache[old] = 1;
          console.warn('*** Mongoose %s is deprecated. Use %s instead.', old, rec);
        }
        return fn
          ? fn.apply(scope || this, arguments)
          : undefined
      }
    }).cache = {};

    process.nextTick(function () {
      var mongoose = require('./index');
      var val = mongoose.set('dep warnings');
      if ('boolean' == typeof val) {
        warn = val;
      } else if ('false' !== process.env.MONGOOSE_DEP_WARNINGS) {
        warn = true;
      }
    });
## virtualtype | lib/virtualtype.js
VirtualType constructor This is what mongoose uses to define virtual attributes via `Schema.prototype.virtual` api: public |
    function VirtualType (options) {
      this.getters = [];
      this.setters = [];
      this.options = options || {};
    }
Adds a getter ## param: Function fn return: VirtualType this api: public |
    VirtualType.prototype.get = function (fn) {
      this.getters.push(fn);
      return this;
    };
Adds a setter ## param: Function fn return: VirtualType this api: public |
    VirtualType.prototype.set = function (fn) {
      this.setters.push(fn);
      return this;
    };
Applies getters ## param: Object value param: Object scope api: public |
    VirtualType.prototype.applyGetters = function (value, scope) {
      var v = value;
      for (var l = this.getters.length - 1; l &gt;= 0; l--){
        v = this.getters[l].call(scope, v);
      }
      return v;
    };
Applies setters ## param: Object value param: Object scope api: public |
    VirtualType.prototype.applySetters = function (value, scope) {
      var v = value;
      for (var l = this.setters.length - 1; l &gt;= 0; l--){
        this.setters[l].call(scope, v);
      }
      return v;
    };

    module.exports = VirtualType;