private

  • index.js

    Mongoose#_applyPlugins(schema)

    Applies global plugins to schema.

    Parameters:

    show code

    1. Mongoose.prototype._applyPlugins = function (schema) {
    2. for (var i = 0, l = this.plugins.length; i < l; i++) {
    3. schema.plugin(this.plugins[i][0], this.plugins[i][1]);
    4. }
    5. }

    Mongoose#Collection()

    The Mongoose Collection constructor


    Mongoose#connect(uri(s), [options], [callback])

    Opens the default mongoose connection.

    Parameters:

    Returns:

    See:

    If arguments are passed, they are proxied to either Connection#open or Connection#openSet appropriately.

    Options passed take precedence over options included in connection strings.

    Example:

    1. mongoose.connect('mongodb://user:pass@localhost:port/database');
    2. // replica sets
    3. var uri = 'mongodb://user:pass@localhost:port/database,mongodb://anotherhost:port,mongodb://yetanother:port';
    4. mongoose.connect(uri);
    5. // with options
    6. mongoose.connect(uri, options);
    7. // connecting to multiple mongos
    8. var uri = 'mongodb://hostA:27501,hostB:27501';
    9. var opts = { mongos: true };
    10. mongoose.connect(uri, opts);

    show code

    1. Mongoose.prototype.connect = function () {
    2. var conn = this.connection;
    3. if (rgxReplSet.test(arguments[0])) {
    4. conn.openSet.apply(conn, arguments);
    5. } else {
    6. conn.open.apply(conn, arguments);
    7. }
    8. return this;
    9. };

    Mongoose#Connection()

    The Mongoose Connection constructor


    Mongoose#createConnection([uri], [options])

    Creates a Connection instance.

    Parameters:

    • [uri] <String> a mongodb:// URI
    • [options] <Object> options to pass to the driver

    Returns:

    See:

    Each connection instance maps to a single database. This method is helpful when mangaging multiple db connections.

    If arguments are passed, they are proxied to either Connection#open or Connection#openSet appropriately. This means we can pass db, server, and replset options to the driver. Note that the safe option specified in your schema will overwrite the safe db option specified here unless you set your schemas safe option to undefined. See this for more information.

    Options passed take precedence over options included in connection strings.

    Example:

    1. // with mongodb:// URI
    2. db = mongoose.createConnection('mongodb://user:pass@localhost:port/database');
    3. // and options
    4. var opts = { db: { native_parser: true }}
    5. db = mongoose.createConnection('mongodb://user:pass@localhost:port/database', opts);
    6. // replica sets
    7. db = mongoose.createConnection('mongodb://user:pass@localhost:port,anotherhost:port,yetanother:port/database');
    8. // and options
    9. var opts = { replset: { strategy: 'ping', rs_name: 'testSet' }}
    10. db = mongoose.createConnection('mongodb://user:pass@localhost:port,anotherhost:port,yetanother:port/database', opts);
    11. // with [host, database_name[, port] signature
    12. db = mongoose.createConnection('localhost', 'database', port)
    13. // and options
    14. var opts = { server: { auto_reconnect: false }, user: 'username', pass: 'mypassword' }
    15. db = mongoose.createConnection('localhost', 'database', port, opts)
    16. // initialize now, connect later
    17. db = mongoose.createConnection();
    18. db.open('localhost', 'database', port, [opts]);

    show code

    1. Mongoose.prototype.createConnection = function () {
    2. var conn = new Connection(this);
    3. this.connections.push(conn);
    4. if (arguments.length) {
    5. if (rgxReplSet.test(arguments[0])) {
    6. conn.openSet.apply(conn, arguments);
    7. } else {
    8. conn.open.apply(conn, arguments);
    9. }
    10. }
    11. return conn;
    12. };

    Mongoose#disconnect([fn])

    Disconnects all connections.

    Parameters:

    • [fn] <Function> called after all connection close.

    Returns:

    show code

    1. Mongoose.prototype.disconnect = function (fn) {
    2. var count = this.connections.length
    3. , error
    4. this.connections.forEach(function(conn){
    5. conn.close(function(err){
    6. if (error) return;
    7. if (err) {
    8. error = err;
    9. if (fn) return fn(err);
    10. throw err;
    11. }
    12. if (fn)
    13. --count || fn();
    14. });
    15. });
    16. return this;
    17. };

    Mongoose#Document()

    The Mongoose Document constructor.


    Mongoose#Error()

    The MongooseError constructor.


    Mongoose#get(key)

    Gets mongoose options

    Parameters:

    Example:

    1. mongoose.get('test') // returns the 'test' value

    Mongoose#model(name, [schema], [collection], [skipInit])

    Defines a model or retrieves it.

    Parameters:

    • name <String> model name
    • [schema] <Schema>
    • [collection] <String> name (optional, induced from model name)
    • [skipInit] <Boolean> whether to skip initialization (defaults to false)

    Models defined on the mongoose instance are available to all connection created by the same mongoose instance.

    Example:

    1. var mongoose = require('mongoose');
    2. // define an Actor model with this mongoose instance
    3. mongoose.model('Actor', new Schema({ name: String }));
    4. // create a new connection
    5. var conn = mongoose.createConnection(..);
    6. // retrieve the Actor model
    7. var Actor = conn.model('Actor');

    When no collection argument is passed, Mongoose produces a collection name by passing the model name to the utils.toCollectionName method. This method pluralizes the name. If you don’t like this behavior, either pass a collection name or set your schemas collection name option.

    Example:

    1. var schema = new Schema({ name: String }, { collection: 'actor' });
    2. // or
    3. schema.set('collection', 'actor');
    4. // or
    5. var collectionName = 'actor'
    6. var M = mongoose.model('Actor', schema, collectionName)

    show code

    ``` Mongoose.prototype.model = function (name, schema, collection, skipInit) { if (‘string’ == typeof schema) {

    1. collection = schema;
    2. schema = false;

    }

    if (utils.isObject(schema) && !(schema instanceof Schema)) {

    1. schema = new Schema(schema);

    }

    if (‘boolean’ === typeof collection) {

    1. skipInit = collection;
    2. collection = null;

    }

    // handle internal options from connection.model() var options; if (skipInit && utils.isObject(skipInit)) {

    1. options = skipInit;
    2. skipInit = true;

    } else {

    1. options = {};

    }

    // look up schema for the collection. this might be a // default schema like system.indexes stored in SchemaDefaults. if (!this.modelSchemas[name]) {

    1. if (!schema && name in SchemaDefaults) {
    2. schema = SchemaDefaults[name];
    3. }
    4. if (schema) {
    5. // cache it so we only apply plugins once
    6. this.modelSchemas[name] = schema;
    7. this._applyPlugins(schema);
    8. } else {
    9. throw new mongoose.Error.MissingSchemaError(name);
    10. }

    }

    var model; var sub;

    // connection.model() may be passing a different schema for // an existing model name. in this case don’t read from cache. if (this.models[name] && false !== options.cache) {

    1. if (schema instanceof Schema && schema != this.models[name].schema) {
    2. throw new mongoose.Error.OverwriteModelError(name);
    3. }
    4. if (collection) {
    5. // subclass current model with alternate collection
    6. model = this.models[name];
    7. schema = model.prototype.schema;
    8. sub = model.__subclass(this.connection, schema, collection);
    9. // do not cache the sub model
    10. return sub;
    11. }
    12. return this.models[name];

    }

    // ensure a schema exists if (!schema) {

    1. schema = this.modelSchemas[name];
    2. if (!schema) {
    3. throw new mongoose.Error.MissingSchemaError(name);
    4. }

    }

    // Apply relevant “global” options to the schema if (!(‘pluralization’ in schema.options)) schema.options.pluralization = this.options.pluralization;

  1. if (!collection) {
  2. collection = schema.get('collection') || format(name, schema.options);
  3. }
  4. var connection = options.connection || this.connection;
  5. model = Model.compile(name, schema, collection, connection, this);
  6. if (!skipInit) {
  7. model.init();
  8. }
  9. if (false === options.cache) {
  10. return model;
  11. }
  12. return this.models[name] = model;
  13. }
  14. ```
  15. ---
  16. ### [Mongoose#Model()](#index_Mongoose-Model)
  17. The Mongoose [Model](#model_Model) constructor.
  18. ---
  19. ### [Mongoose#modelNames()](#index_Mongoose-modelNames)
  20. Returns an array of model names created on this instance of Mongoose.
  21. #### Returns:
  22. - &lt;[Array](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array)&gt;
  23. #### Note:
  24. *Does not include names of models created using `connection.model()`.*
  25. show code
  26. ```
  27. Mongoose.prototype.modelNames = function () {
  28. var names = Object.keys(this.models);
  29. return names;
  30. }
  31. ```
  32. ---
  33. ### [Mongoose()](#index_Mongoose)
  34. Mongoose constructor.
  35. The exports object of the `mongoose` module is an instance of this class.
  36. Most apps will only use this one instance.
  37. show code
  38. ```
  39. function Mongoose () {
  40. this.connections = [];
  41. this.plugins = [];
  42. this.models = {};
  43. this.modelSchemas = {};
  44. // default global options
  45. this.options = {
  46. pluralization: true
  47. };
  48. var conn = this.createConnection(); // default connection
  49. conn.models = this.models;
  50. };
  51. ```
  52. ---
  53. ### [Mongoose#Mongoose()](#index_Mongoose-Mongoose)
  54. The Mongoose constructor
  55. The exports of the mongoose module is an instance of this class.
  56. #### Example:
  57. ```
  58. var mongoose = require('mongoose');
  59. var mongoose2 = new mongoose.Mongoose();
  60. ```
  61. ---
  62. ### [Mongoose#plugin(`fn`, `[opts]`)](#index_Mongoose-plugin)
  63. Declares a global plugin executed on all Schemas.
  64. #### Parameters:
  65. - `fn` &lt;[Function](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function)&gt; plugin callback
  66. - `[opts]` &lt;[Object](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object)&gt; optional options
  67. #### Returns:
  68. - &lt;[Mongoose](#index_Mongoose)&gt; this
  69. #### See:
  70. - [plugins]($ed3b83fd8960771d.md "plugins")
  71. Equivalent to calling `.plugin(fn)` on each Schema you create.
  72. show code
  73. ```
  74. Mongoose.prototype.plugin = function (fn, opts) {
  75. this.plugins.push([fn, opts]);
  76. return this;
  77. };
  78. ```
  79. ---
  80. ### [Mongoose#Promise()](#index_Mongoose-Promise)
  81. The Mongoose [Promise](#promise_Promise) constructor.
  82. ---
  83. ### [Mongoose#Query()](#index_Mongoose-Query)
  84. The Mongoose [Query](#query_Query) constructor.
  85. ---
  86. ### [Mongoose#Schema()](#index_Mongoose-Schema)
  87. The Mongoose [Schema](#schema_Schema) constructor
  88. #### Example:
  89. ```
  90. var mongoose = require('mongoose');
  91. var Schema = mongoose.Schema;
  92. var CatSchema = new Schema(..);
  93. ```
  94. ---
  95. ### [Mongoose#SchemaType()](#index_Mongoose-SchemaType)
  96. The Mongoose [SchemaType](#schematype_SchemaType) constructor
  97. ---
  98. ### [Mongoose#set(`key`, `value`)](#index_Mongoose-set)
  99. Sets mongoose options
  100. #### Parameters:
  101. - `key` &lt;[String](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String)&gt;
  102. - `value` &lt;[String](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String)&gt;
  103. #### Example:
  104. ```
  105. mongoose.set('test', value) // sets the 'test' option to `value`
  106. mongoose.set('debug', true) // enable logging collection methods + arguments to the console
  107. ```
  108. show code
  109. ```
  110. Mongoose.prototype.set = function (key, value) {
  111. if (arguments.length == 1) {
  112. return this.options[key];
  113. }
  114. this.options[key] = value;
  115. return this;
  116. };
  117. ```
  118. ---
  119. ### [()](#index_)
  120. Expose connection states for user-land
  121. show code
  122. ```
  123. Mongoose.prototype.STATES = STATES;
  124. ```
  125. ---
  126. ### [Mongoose#VirtualType()](#index_Mongoose-VirtualType)
  127. The Mongoose [VirtualType](#virtualtype_VirtualType) constructor
  128. ---
  129. ### [Mongoose#connection](#index_Mongoose-connection)
  130. The default connection of the mongoose module.
  131. #### Example:
  132. ```
  133. var mongoose = require('mongoose');
  134. mongoose.connect(...);
  135. mongoose.connection.on('error', cb);
  136. ```
  137. This is the connection used by default for every model created using [mongoose.model](#index_Mongoose-model).
  138. show code
  139. ```
  140. Mongoose.prototype.__defineGetter__('connection', function(){
  141. return this.connections[0];
  142. });
  143. ```
  144. #### Returns:
  145. - &lt;[Connection](#connection_Connection)&gt;
  146. ---
  147. ### [Mongoose#mongo](#index_Mongoose-mongo)
  148. The [node-mongodb-native](https://github.com/mongodb/node-mongodb-native) driver Mongoose uses.
  149. show code
  150. ```
  151. Mongoose.prototype.mongo = require('mongodb');
  152. ```
  153. ---
  154. ### [Mongoose#mquery](#index_Mongoose-mquery)
  155. The [mquery](https://github.com/aheckmann/mquery) query builder Mongoose uses.
  156. show code
  157. ```
  158. Mongoose.prototype.mquery = require('mquery');
  159. // Hack for Automattic/mongoose#2864
  160. delete Mongoose.prototype.mquery.then;
  161. ```
  162. ---
  163. ### [Mongoose#SchemaTypes](#index_Mongoose-SchemaTypes)
  164. The various Mongoose SchemaTypes.
  165. #### Note:
  166. *Alias of mongoose.Schema.Types for backwards compatibility.*
  167. show code
  168. ```
  169. Mongoose.prototype.SchemaTypes = Schema.Types;
  170. ```
  171. #### See:
  172. - [Schema.SchemaTypes](#schema_Schema.Types "Schema.SchemaTypes")
  173. ---
  174. ### [Mongoose#Types](#index_Mongoose-Types)
  175. The various Mongoose Types.
  176. #### Example:
  177. ```
  178. var mongoose = require('mongoose');
  179. var array = mongoose.Types.Array;
  180. ```
  181. #### Types:
  182. - [ObjectId](#types-objectid-js)
  183. - [Buffer](#types-buffer-js)
  184. - [SubDocument](#types-embedded-js)
  185. - [Array](#types-array-js)
  186. - [DocumentArray](#types-documentarray-js)
  187. Using this exposed access to the `ObjectId` type, we can construct ids on demand.
  188. ```
  189. var ObjectId = mongoose.Types.ObjectId;
  190. var id1 = new ObjectId;
  191. ```
  192. show code
  193. ```
  194. Mongoose.prototype.Types = Types;
  195. ```
  196. ---
  197. ### [Mongoose#version](#index_Mongoose-version)
  198. The Mongoose version
  199. show code
  200. ```
  201. Mongoose.prototype.version = pkg.version;
  202. ```
  203. ---
  • querystream.js

    QueryStream#__next()

    Pulls the next doc from the cursor.

    See:

    show code

    1. QueryStream.prototype.__next = function () {
    2. if (this.paused || this._destroyed)
    3. return this._running = false;
    4. var self = this;
    5. self._inline = T_INIT;
    6. self._cursor.nextObject(function cursorcb (err, doc) {
    7. self._onNextObject(err, doc);
    8. });
    9. // if onNextObject() was already called in this tick
    10. // return ourselves to the trampoline.
    11. if (T_CONT === this._inline) {
    12. return true;
    13. } else {
    14. // onNextObject() hasn't fired yet. tell onNextObject
    15. // that its ok to call _next b/c we are not within
    16. // the trampoline anymore.
    17. this._inline = T_IDLE;
    18. }
    19. }

    QueryStream#_init()

    Initializes the query.

    show code

    1. QueryStream.prototype._init = function () {
    2. if (this._destroyed) return;
    3. var query = this.query
    4. , model = query.model
    5. , options = query._optionsForExec(model)
    6. , self = this
    7. try {
    8. query.cast(model);
    9. } catch (err) {
    10. return self.destroy(err);
    11. }
    12. self._fields = utils.clone(query._fields);
    13. options.fields = query._castFields(self._fields);
    14. model.collection.find(query._conditions, options, function (err, cursor) {
    15. if (err) return self.destroy(err);
    16. self._cursor = cursor;
    17. self._next();
    18. });
    19. }

    QueryStream#_next()

    Trampoline for pulling the next doc from cursor.

    See:

    show code

    1. QueryStream.prototype._next = function _next () {
    2. if (this.paused || this._destroyed) {
    3. return this._running = false;
    4. }
    5. this._running = true;
    6. if (this._buffer && this._buffer.length) {
    7. var arg;
    8. while (!this.paused && !this._destroyed && (arg = this._buffer.shift())) {
    9. this._onNextObject.apply(this, arg);
    10. }
    11. }
    12. // avoid stack overflows with large result sets.
    13. // trampoline instead of recursion.
    14. while (this.__next()) {}
    15. }

    QueryStream#_onNextObject(err, doc)

    Transforms raw docs returned from the cursor into a model instance.

    Parameters:

    show code

    1. QueryStream.prototype._onNextObject = function _onNextObject (err, doc) {
    2. if (this._destroyed) return;
    3. if (this.paused) {
    4. this._buffer || (this._buffer = []);
    5. this._buffer.push([err, doc]);
    6. return this._running = false;
    7. }
    8. if (err) return this.destroy(err);
    9. // when doc is null we hit the end of the cursor
    10. if (!doc) {
    11. this.emit('end');
    12. return this.destroy();
    13. }
    14. var opts = this.query._mongooseOptions;
    15. if (!opts.populate) {
    16. return true === opts.lean
    17. ? emit(this, doc)
    18. : createAndEmit(this, doc);
    19. }
    20. var self = this;
    21. var pop = helpers.preparePopulationOptionsMQ(self.query, self.query._mongooseOptions);
    22. self.query.model.populate(doc, pop, function (err, doc) {
    23. if (err) return self.destroy(err);
    24. return true === opts.lean
    25. ? emit(self, doc)
    26. : createAndEmit(self, doc);
    27. })
    28. }
    29. function createAndEmit (self, doc) {
    30. var instance = helpers.createModel(self.query.model, doc, self._fields);
    31. instance.init(doc, function (err) {
    32. if (err) return self.destroy(err);
    33. emit(self, instance);
    34. });
    35. }

    QueryStream#destroy([err])

    Destroys the stream, closing the underlying cursor. No more events will be emitted.

    Parameters:

    show code

    1. QueryStream.prototype.destroy = function (err) {
    2. if (this._destroyed) return;
    3. this._destroyed = true;
    4. this._running = false;
    5. this.readable = false;
    6. if (this._cursor) {
    7. this._cursor.close();
    8. }
    9. if (err) {
    10. this.emit('error', err);
    11. }
    12. this.emit('close');
    13. }

    QueryStream#pause()

    Pauses this stream.

    show code

    1. QueryStream.prototype.pause = function () {
    2. this.paused = true;
    3. }

    QueryStream#pipe()

    Pipes this query stream into another stream. This method is inherited from NodeJS Streams.

    See:

    Example:

    1. query.stream().pipe(writeStream [, options])

    QueryStream(query, [options])

    Provides a Node.js 0.8 style ReadStream interface for Queries.

    Parameters:

    Inherits:

    Events:

    • data: emits a single Mongoose document

    • error: emits when an error occurs during streaming. This will emit before the close event.

    • close: emits when the stream reaches the end of the cursor or an error occurs, or the stream is manually destroyed. After this event, no more events are emitted.

    1. var stream = Model.find().stream();
    2. stream.on('data', function (doc) {
    3. // do something with the mongoose document
    4. }).on('error', function (err) {
    5. // handle the error
    6. }).on('close', function () {
    7. // the stream is closed
    8. });

    The stream interface allows us to simply “plug-in” to other Node.js 0.8 style write streams.

    1. Model.where('created').gte(twoWeeksAgo).stream().pipe(writeStream);

    Valid options

    • transform: optional function which accepts a mongoose document. The return value of the function will be emitted on data.

    Example

    1. // JSON.stringify all documents before emitting
    2. var stream = Thing.find().stream({ transform: JSON.stringify });
    3. stream.pipe(writeStream);

    NOTE: plugging into an HTTP response will \not* work out of the box. Those streams expect only strings or buffers to be emitted, so first formatting our documents as strings/buffers is necessary.*

    NOTE: these streams are Node.js 0.8 style read streams which differ from Node.js 0.10 style. Node.js 0.10 streams are not well tested yet and are not guaranteed to work.

    show code

    1. function QueryStream (query, options) {
    2. Stream.call(this);
    3. this.query = query;
    4. this.readable = true;
    5. this.paused = false;
    6. this._cursor = null;
    7. this._destroyed = null;
    8. this._fields = null;
    9. this._buffer = null;
    10. this._inline = T_INIT;
    11. this._running = false;
    12. this._transform = options && 'function' == typeof options.transform
    13. ? options.transform
    14. : K;
    15. // give time to hook up events
    16. var self = this;
    17. process.nextTick(function () {
    18. self._init();
    19. });
    20. }

    QueryStream#resume()

    Resumes this stream.

    show code

    1. QueryStream.prototype.resume = function () {
    2. this.paused = false;
    3. if (!this._cursor) {
    4. // cannot start if not initialized
    5. return;
    6. }
    7. // are we within the trampoline?
    8. if (T_INIT === this._inline) {
    9. return;
    10. }
    11. if (!this._running) {
    12. // outside QueryStream control, need manual restart
    13. return this._next();
    14. }
    15. }

    QueryStream#paused

    Flag stating whether or not this stream is paused.

    show code

    1. QueryStream.prototype.paused;
    2. // trampoline flags
    3. var T_INIT = 0;
    4. var T_IDLE = 1;
    5. var T_CONT = 2;

    QueryStream#readable

    Flag stating whether or not this stream is readable.

    show code

    1. QueryStream.prototype.readable;

  • connection.js

    Connection(base)

    Connection constructor

    Parameters:

    Inherits:

    Events:

    • connecting: Emitted when connection.{open,openSet}() is executed on this connection.

    • connected: Emitted when this connection successfully connects to the db. May be emitted multiple times in reconnected scenarios.

    • open: Emitted after we connected and onOpen is executed on all of this connections models.

    • disconnecting: Emitted when connection.close() was executed.

    • disconnected: Emitted after getting disconnected from the db.

    • close: Emitted after we disconnected and onClose executed on all of this connections models.

    • reconnected: Emitted after we connected and subsequently disconnected, followed by successfully another successfull connection.

    • error: Emitted when an error occurs on this connection.

    • fullsetup: Emitted in a replica-set scenario, when all nodes specified in the connection string are connected.

    For practical reasons, a Connection equals a Db.

    show code

    1. function Connection (base) {
    2. this.base = base;
    3. this.collections = {};
    4. this.models = {};
    5. this.replica = false;
    6. this.hosts = null;
    7. this.host = null;
    8. this.port = null;
    9. this.user = null;
    10. this.pass = null;
    11. this.name = null;
    12. this.options = null;
    13. this.otherDbs = [];
    14. this._readyState = STATES.disconnected;
    15. this._closeCalled = false;
    16. this._hasOpened = false;
    17. };

    Connection#open(connection_string, [database], [port], [options], [callback])

    Opens the connection to MongoDB.

    Parameters:

    • connection_string <String> mongodb://uri or the host to which you are connecting
    • [database] <String> database name
    • [port] <Number> database port
    • [options] <Object> options
    • [callback] <Function>

    See:

    options is a hash with the following possible properties:

    1. db - passed to the connection db instance
    2. server - passed to the connection server instance(s)
    3. replset - passed to the connection ReplSet instance
    4. user - username for authentication
    5. pass - password for authentication
    6. auth - options for authentication (see http://mongodb.github.com/node-mongodb-native/api-generated/db.html#authenticate)

    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.

    Options passed take precedence over options included in connection strings.

    show code

    1. Connection.prototype.open = function (host, database, port, options, callback) {
    2. var self = this
    3. , parsed
    4. , uri;
    5. if ('string' === typeof database) {
    6. switch (arguments.length) {
    7. case 2:
    8. port = 27017;
    9. case 3:
    10. switch (typeof port) {
    11. case 'function':
    12. callback = port, port = 27017;
    13. break;
    14. case 'object':
    15. options = port, port = 27017;
    16. break;
    17. }
    18. break;
    19. case 4:
    20. if ('function' === typeof options)
    21. callback = options, options = {};
    22. }
    23. } else {
    24. switch (typeof database) {
    25. case 'function':
    26. callback = database, database = undefined;
    27. break;
    28. case 'object':
    29. options = database;
    30. database = undefined;
    31. callback = port;
    32. break;
    33. }
    34. if (!rgxProtocol.test(host)) {
    35. host = 'mongodb://' + host;
    36. }
    37. try {
    38. parsed = muri(host);
    39. } catch (err) {
    40. this.error(err, callback);
    41. return this;
    42. }
    43. database = parsed.db;
    44. host = parsed.hosts[0].host || parsed.hosts[0].ipc;
    45. port = parsed.hosts[0].port || 27017;
    46. }
    47. this.options = this.parseOptions(options, parsed && parsed.options);
    48. // make sure we can open
    49. if (STATES.disconnected !== this.readyState) {
    50. var err = new Error('Trying to open unclosed connection.');
    51. err.state = this.readyState;
    52. this.error(err, callback);
    53. return this;
    54. }
    55. if (!host) {
    56. this.error(new Error('Missing hostname.'), callback);
    57. return this;
    58. }
    59. if (!database) {
    60. this.error(new Error('Missing database name.'), callback);
    61. return this;
    62. }
    63. // authentication
    64. if (options && options.user && options.pass) {
    65. this.user = options.user;
    66. this.pass = options.pass;
    67. } else if (parsed && parsed.auth) {
    68. this.user = parsed.auth.user;
    69. this.pass = parsed.auth.pass;
    70. // Check hostname for user/pass
    71. } else if (/@/.test(host) && /:/.test(host.split('@')[0])) {
    72. host = host.split('@');
    73. var auth = host.shift().split(':');
    74. host = host.pop();
    75. this.user = auth[0];
    76. this.pass = auth[1];
    77. } else {
    78. this.user = this.pass = undefined;
    79. }
    80. this.name = database;
    81. this.host = host;
    82. this.port = port;
    83. this._open(callback);
    84. return this;
    85. };

    Connection#openSet(uris, [database], [options], [callback])

    Opens the connection to a replica set.

    Parameters:

    • uris <String> comma-separated mongodb:// `URI`s
    • [database] <String> database name if not included in `uris`
    • [options] <Object> passed to the internal driver
    • [callback] <Function>

    See:

    Example:

    1. var db = mongoose.createConnection();
    2. db.openSet("mongodb://user:pwd@localhost:27020/testing,mongodb://example.com:27020,mongodb://localhost:27019");

    The database name and/or auth need only be included in one URI.
    The options is a hash which is passed to the internal driver connection object.

    Valid options

    1. db - passed to the connection db instance
    2. server - passed to the connection server instance(s)
    3. replset - passed to the connection ReplSetServer instance
    4. user - username for authentication
    5. pass - password for authentication
    6. auth - options for authentication (see http://mongodb.github.com/node-mongodb-native/api-generated/db.html#authenticate)
    7. mongos - Boolean - if true, enables High Availability support for mongos

    Options passed take precedence over options included in connection strings.

    Notes:

    If connecting to multiple mongos servers, set the mongos option to true.

    1. conn.open('mongodb://mongosA:27501,mongosB:27501', { mongos: true }, cb);

    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.

    Options passed take precedence over options included in connection strings.

    show code

    1. Connection.prototype.openSet = function (uris, database, options, callback) {
    2. if (!rgxProtocol.test(uris)) {
    3. uris = 'mongodb://' + uris;
    4. }
    5. var self = this;
    6. switch (arguments.length) {
    7. case 3:
    8. switch (typeof database) {
    9. case 'string':
    10. this.name = database;
    11. break;
    12. case 'object':
    13. callback = options;
    14. options = database;
    15. database = null;
    16. break;
    17. }
    18. if ('function' === typeof options) {
    19. callback = options;
    20. options = {};
    21. }
    22. break;
    23. case 2:
    24. switch (typeof database) {
    25. case 'string':
    26. this.name = database;
    27. break;
    28. case 'function':
    29. callback = database, database = null;
    30. break;
    31. case 'object':
    32. options = database, database = null;
    33. break;
    34. }
    35. }
    36. var parsed;
    37. try {
    38. parsed = muri(uris);
    39. } catch (err) {
    40. this.error(err, callback);
    41. return this;
    42. }
    43. if (!this.name) {
    44. this.name = parsed.db;
    45. }
    46. this.hosts = parsed.hosts;
    47. this.options = this.parseOptions(options, parsed && parsed.options);
    48. this.replica = true;
    49. if (!this.name) {
    50. this.error(new Error('No database name provided for replica set'), callback);
    51. return this;
    52. }
    53. // authentication
    54. if (options && options.user && options.pass) {
    55. this.user = options.user;
    56. this.pass = options.pass;
    57. } else if (parsed && parsed.auth) {
    58. this.user = parsed.auth.user;
    59. this.pass = parsed.auth.pass;
    60. } else {
    61. this.user = this.pass = undefined;
    62. }
    63. this._open(callback);
    64. return this;
    65. };

    Connection#error(err, callback)

    error

    Parameters:

    Graceful error handling, passes error to callback
    if available, else emits error on the connection.

    show code

    1. Connection.prototype.error = function (err, callback) {
    2. if (callback) return callback(err);
    3. this.emit('error', err);
    4. }

    Connection#_open(callback)

    Handles opening the connection with the appropriate method based on connection type.

    Parameters:

    show code

    1. Connection.prototype._open = function (callback) {
    2. this.readyState = STATES.connecting;
    3. this._closeCalled = false;
    4. var self = this;
    5. var method = this.replica
    6. ? 'doOpenSet'
    7. : 'doOpen';
    8. // open connection
    9. this[method](function (err) {
    10. if (err) {
    11. self.readyState = STATES.disconnected;
    12. if (self._hasOpened) {
    13. if (callback) callback(err);
    14. } else {
    15. self.error(err, callback);
    16. }
    17. return;
    18. }
    19. self.onOpen(callback);
    20. });
    21. }

    Connection#onOpen()

    Called when the connection is opened

    show code

    1. Connection.prototype.onOpen = function (callback) {
    2. var self = this;
    3. function open(err, isAuth) {
    4. if (err) {
    5. self.readyState = isAuth ? STATES.unauthorized : STATES.disconnected;
    6. if (self._hasOpened) {
    7. if (callback) callback(err);
    8. } else {
    9. self.error(err, callback);
    10. }
    11. return;
    12. }
    13. self.readyState = STATES.connected;
    14. // avoid having the collection subscribe to our event emitter
    15. // to prevent 0.3 warning
    16. for (var i in self.collections)
    17. self.collections[i].onOpen();
    18. callback && callback();
    19. self.emit('open');
    20. };
    21. // re-authenticate
    22. if (self.user && self.pass) {
    23. self.db.authenticate(self.user, self.pass, self.options.auth, function(err) {
    24. open(err, true);
    25. });
    26. } else {
    27. open();
    28. }
    29. };

    Connection#close([callback])

    Closes the connection

    Parameters:

    Returns:

    show code

    1. Connection.prototype.close = function (callback) {
    2. var self = this;
    3. this._closeCalled = true;
    4. switch (this.readyState){
    5. case 0: // disconnected
    6. callback && callback();
    7. break;
    8. case 1: // connected
    9. case 4: // unauthorized
    10. this.readyState = STATES.disconnecting;
    11. this.doClose(function(err){
    12. if (err){
    13. self.error(err, callback);
    14. } else {
    15. self.onClose();
    16. callback && callback();
    17. }
    18. });
    19. break;
    20. case 2: // connecting
    21. this.once('open', function(){
    22. self.close(callback);
    23. });
    24. break;
    25. case 3: // disconnecting
    26. if (!callback) break;
    27. this.once('close', function () {
    28. callback();
    29. });
    30. break;
    31. }
    32. return this;
    33. };

    Connection#onClose()

    Called when the connection closes

    show code

    1. Connection.prototype.onClose = function () {
    2. this.readyState = STATES.disconnected;
    3. // avoid having the collection subscribe to our event emitter
    4. // to prevent 0.3 warning
    5. for (var i in this.collections)
    6. this.collections[i].onClose();
    7. this.emit('close');
    8. };

    Connection#collection(name, [options])

    Retrieves a collection, creating it if not cached.

    Parameters:

    • name <String> of the collection
    • [options] <Object> optional collection options

    Returns:

    Not typically needed by applications. Just talk to your collection through your model.

    show code

    1. Connection.prototype.collection = function (name, options) {
    2. if (!(name in this.collections))
    3. this.collections[name] = new Collection(name, this, options);
    4. return this.collections[name];
    5. };

    Connection#model(name, [schema], [collection])

    Defines or retrieves a model.

    Parameters:

    • name <String> the model name
    • [schema] <Schema> a schema. necessary when defining a model
    • [collection] <String> name of mongodb collection (optional) if not given it will be induced from model name

    Returns:

    • <Model> The compiled model

    See:

    1. var mongoose = require('mongoose');
    2. var db = mongoose.createConnection(..);
    3. db.model('Venue', new Schema(..));
    4. var Ticket = db.model('Ticket', new Schema(..));
    5. var Venue = db.model('Venue');

    When no collection argument is passed, Mongoose produces a collection name by passing the model name to the utils.toCollectionName method. This method pluralizes the name. If you don’t like this behavior, either pass a collection name or set your schemas collection name option.

    Example:

    1. var schema = new Schema({ name: String }, { collection: 'actor' });
    2. // or
    3. schema.set('collection', 'actor');
    4. // or
    5. var collectionName = 'actor'
    6. var M = conn.model('Actor', schema, collectionName)

    show code

    1. Connection.prototype.model = function (name, schema, collection) {
    2. // collection name discovery
    3. if ('string' == typeof schema) {
    4. collection = schema;
    5. schema = false;
    6. }
    7. if (utils.isObject(schema) && !(schema instanceof Schema)) {
    8. schema = new Schema(schema);
    9. }
    10. if (this.models[name] && !collection) {
    11. // model exists but we are not subclassing with custom collection
    12. if (schema instanceof Schema && schema != this.models[name].schema) {
    13. throw new MongooseError.OverwriteModelError(name);
    14. }
    15. return this.models[name];
    16. }
    17. var opts = { cache: false, connection: this }
    18. var model;
    19. if (schema instanceof Schema) {
    20. // compile a model
    21. model = this.base.model(name, schema, collection, opts)
    22. // only the first model with this name is cached to allow
    23. // for one-offs with custom collection names etc.
    24. if (!this.models[name]) {
    25. this.models[name] = model;
    26. }
    27. model.init();
    28. return model;
    29. }
    30. if (this.models[name] && collection) {
    31. // subclassing current model with alternate collection
    32. model = this.models[name];
    33. schema = model.prototype.schema;
    34. var sub = model.__subclass(this, schema, collection);
    35. // do not cache the sub model
    36. return sub;
    37. }
    38. // lookup model in mongoose module
    39. model = this.base.models[name];
    40. if (!model) {
    41. throw new MongooseError.MissingSchemaError(name);
    42. }
    43. if (this == model.prototype.db
    44. && (!collection || collection == model.collection.name)) {
    45. // model already uses this connection.
    46. // only the first model with this name is cached to allow
    47. // for one-offs with custom collection names etc.
    48. if (!this.models[name]) {
    49. this.models[name] = model;
    50. }
    51. return model;
    52. }
    53. return this.models[name] = model.__subclass(this, schema, collection);
    54. }

    Connection#modelNames()

    Returns an array of model names created on this connection.

    Returns:

    show code

    1. Connection.prototype.modelNames = function () {
    2. return Object.keys(this.models);
    3. }

    Connection#setProfiling(level, [ms], callback)

    Set profiling level.

    Parameters:

    • level <Number, String> either off (0), slow (1), or all (2)
    • [ms] <Number> the threshold in milliseconds above which queries will be logged when in `slow` mode. defaults to 100.
    • callback <Function>

    show code

    1. Connection.prototype.setProfiling = function (level, ms, callback) {
    2. if (STATES.connected !== this.readyState) {
    3. return this.on('open', this.setProfiling.bind(this, level, ms, callback));
    4. }
    5. if (!callback) callback = ms, ms = 100;
    6. var cmd = {};
    7. switch (level) {
    8. case 0:
    9. case 'off':
    10. cmd.profile = 0;
    11. break;
    12. case 1:
    13. case 'slow':
    14. cmd.profile = 1;
    15. if ('number' !== typeof ms) {
    16. ms = parseInt(ms, 10);
    17. if (isNaN(ms)) ms = 100;
    18. }
    19. cmd.slowms = ms;
    20. break;
    21. case 2:
    22. case 'all':
    23. cmd.profile = 2;
    24. break;
    25. default:
    26. return callback(new Error('Invalid profiling level: '+ level));
    27. }
    28. this.db.executeDbCommand(cmd, function (err, resp) {
    29. if (err) return callback(err);
    30. var doc = resp.documents[0];
    31. err = 1 === doc.ok
    32. ? null
    33. : new Error('Could not set profiling level to: '+ level)
    34. callback(err, doc);
    35. });
    36. };

    Connection#db

    The mongodb.Db instance, set when the connection is opened

    show code

    1. Connection.prototype.db;

    Connection#collections

    A hash of the collections associated with this connection

    show code

    1. Connection.prototype.collections;

    Connection#readyState

    Connection ready state

    • 0 = disconnected
    • 1 = connected
    • 2 = connecting
    • 3 = disconnecting

    Each state change emits its associated event name.

    Example

    1. conn.on('connected', callback);
    2. conn.on('disconnected', callback);

    show code

    1. Object.defineProperty(Connection.prototype, 'readyState', {
    2. get: function(){ return this._readyState; }
    3. , set: function (val) {
    4. if (!(val in STATES)) {
    5. throw new Error('Invalid connection state: ' + val);
    6. }
    7. if (this._readyState !== val) {
    8. this._readyState = val;
    9. // loop over the otherDbs on this connection and change their state
    10. for (var i=0; i < this.otherDbs.length; i++) {
    11. this.otherDbs[i].readyState = val;
    12. }
    13. if (STATES.connected === val)
    14. this._hasOpened = true;
    15. this.emit(STATES[val]);
    16. }
    17. }
    18. });

  • utils.js

    exports.mergeClone(to, from)

    merges to with a copy of from

    show code

    1. exports.mergeClone = function(to, from) {
    2. var keys = Object.keys(from)
    3. , i = keys.length
    4. , key
    5. while (i--) {
    6. key = keys[i];
    7. if ('undefined' === typeof to[key]) {
    8. // make sure to retain key order here because of a bug handling the $each
    9. // operator in mongodb 2.4.4
    10. to[key] = exports.clone(from[key], { retainKeyOrder : 1});
    11. } else {
    12. if (exports.isObject(from[key])) {
    13. exports.mergeClone(to[key], from[key]);
    14. } else {
    15. // make sure to retain key order here because of a bug handling the
    16. // $each operator in mongodb 2.4.4
    17. to[key] = exports.clone(from[key], { retainKeyOrder : 1});
    18. }
    19. }
    20. }
    21. }

    Parameters:


    exports.pluralization

    Pluralization rules.

    show code

    1. exports.pluralization = [
    2. [/(m)an$/gi, '$1en'],
    3. [/(pe)rson$/gi, '$1ople'],
    4. [/(child)$/gi, '$1ren'],
    5. [/^(ox)$/gi, '$1en'],
    6. [/(ax|test)is$/gi, '$1es'],
    7. [/(octop|vir)us$/gi, '$1i'],
    8. [/(alias|status)$/gi, '$1es'],
    9. [/(bu)s$/gi, '$1ses'],
    10. [/(buffal|tomat|potat)o$/gi, '$1oes'],
    11. [/([ti])um$/gi, '$1a'],
    12. [/sis$/gi, 'ses'],
    13. [/(?:([^f])fe|([lr])f)$/gi, '$1$2ves'],
    14. [/(hive)$/gi, '$1s'],
    15. [/([^aeiouy]|qu)y$/gi, '$1ies'],
    16. [/(x|ch|ss|sh)$/gi, '$1es'],
    17. [/(matr|vert|ind)ix|ex$/gi, '$1ices'],
    18. [/([m|l])ouse$/gi, '$1ice'],
    19. [/(quiz)$/gi, '$1zes'],
    20. [/s$/gi, 's'],
    21. [/([^a-z])$/, '$1'],
    22. [/$/gi, 's']
    23. ];
    24. var rules = exports.pluralization;

    These rules are applied while processing the argument to toCollectionName.


    exports.uncountables

    Uncountable words.

    show code

    1. exports.uncountables = [
    2. 'advice',
    3. 'energy',
    4. 'excretion',
    5. 'digestion',
    6. 'cooperation',
    7. 'health',
    8. 'justice',
    9. 'labour',
    10. 'machinery',
    11. 'equipment',
    12. 'information',
    13. 'pollution',
    14. 'sewage',
    15. 'paper',
    16. 'money',
    17. 'species',
    18. 'series',
    19. 'rain',
    20. 'rice',
    21. 'fish',
    22. 'sheep',
    23. 'moose',
    24. 'deer',
    25. 'news',
    26. 'expertise',
    27. 'status',
    28. 'media'
    29. ];
    30. var uncountables = exports.uncountables;

    These words are applied while processing the argument to toCollectionName.


  • drivers/node-mongodb-native/collection.js

    NativeCollection#getIndexes(callback)

    Retreives information about this collections indexes.

    Parameters:


    NativeCollection()

    A node-mongodb-native collection implementation.

    Inherits:

    All methods methods from the node-mongodb-native driver are copied and wrapped in queue management.

    show code

    1. function NativeCollection () {
    2. this.collection = null;
    3. MongooseCollection.apply(this, arguments);
    4. }

    NativeCollection#onClose()

    Called when the connection closes

    show code

    1. NativeCollection.prototype.onClose = function () {
    2. MongooseCollection.prototype.onClose.call(this);
    3. };

    NativeCollection#onOpen()

    Called when the connection opens.

    show code

    1. NativeCollection.prototype.onOpen = function () {
    2. var self = this;
    3. // always get a new collection in case the user changed host:port
    4. // of parent db instance when re-opening the connection.
    5. if (!self.opts.capped.size) {
    6. // non-capped
    7. return self.conn.db.collection(self.name, callback);
    8. }
    9. // capped
    10. return self.conn.db.collection(self.name, function (err, c) {
    11. if (err) return callback(err);
    12. // discover if this collection exists and if it is capped
    13. self.conn.db.collection( 'system.namespaces', function(err, namespaces) {
    14. var namespaceName = self.conn.db.databaseName + '.' + self.name;
    15. namespaces.findOne({ name : namespaceName }, function(err, doc) {
    16. if (err) {
    17. return callback(err);
    18. }
    19. var exists = !!doc;
    20. if (exists) {
    21. if (doc.options && doc.options.capped) {
    22. callback(null, c);
    23. } else {
    24. var msg = 'A non-capped collection exists with the name: '+ self.name +'
    25. '
    26. + ' To use this collection as a capped collection, please '
    27. + 'first convert it.
    28. '
    29. + ' http://www.mongodb.org/display/DOCS/Capped+Collections#CappedCollections-Convertingacollectiontocapped'
    30. err = new Error(msg);
    31. callback(err);
    32. }
    33. } else {
    34. // create
    35. var opts = utils.clone(self.opts.capped);
    36. opts.capped = true;
    37. self.conn.db.createCollection(self.name, opts, callback);
    38. }
    39. });
    40. });
    41. });
    42. function callback (err, collection) {
    43. if (err) {
    44. // likely a strict mode error
    45. self.conn.emit('error', err);
    46. } else {
    47. self.collection = collection;
    48. MongooseCollection.prototype.onOpen.call(self);
    49. }
    50. };
    51. };

  • drivers/node-mongodb-native/connection.js

    NativeConnection#doClose(fn)

    Closes the connection

    Parameters:

    Returns:

    show code

    1. NativeConnection.prototype.doClose = function (fn) {
    2. this.db.close();
    3. if (fn) fn();
    4. return this;
    5. }

    NativeConnection#doOpen(fn)

    Opens the connection to MongoDB.

    Parameters:

    Returns:

    show code

    1. NativeConnection.prototype.doOpen = function (fn) {
    2. if (this.db) {
    3. mute(this);
    4. }
    5. var server = new Server(this.host, this.port, this.options.server);
    6. this.db = new Db(this.name, server, this.options.db);
    7. var self = this;
    8. this.db.open(function (err) {
    9. if (err) return fn(err);
    10. listen(self);
    11. fn();
    12. });
    13. return this;
    14. };

    NativeConnection#doOpenSet(fn)

    Opens a connection to a MongoDB ReplicaSet.

    Parameters:

    Returns:

    See description of doOpen for server options. In this case options.replset is also passed to ReplSetServers.

    show code

    1. NativeConnection.prototype.doOpenSet = function (fn) {
    2. if (this.db) {
    3. mute(this);
    4. }
    5. var servers = []
    6. , self = this;
    7. this.hosts.forEach(function (server) {
    8. var host = server.host || server.ipc;
    9. var port = server.port || 27017;
    10. servers.push(new Server(host, port, self.options.server));
    11. })
    12. var server = this.options.mongos
    13. ? new Mongos(servers, this.options.mongos)
    14. : new ReplSetServers(servers, this.options.replset);
    15. this.db = new Db(this.name, server, this.options.db);
    16. this.db.on('fullsetup', function () {
    17. self.emit('fullsetup')
    18. });
    19. this.db.open(function (err) {
    20. if (err) return fn(err);
    21. fn();
    22. listen(self);
    23. });
    24. return this;
    25. };

    NativeConnection()

    A node-mongodb-native connection implementation.

    Inherits:

    show code

    1. function NativeConnection() {
    2. MongooseConnection.apply(this, arguments);
    3. this._listening = false;
    4. };

    NativeConnection#parseOptions(passed, [connStrOptions])

    Prepares default connection options for the node-mongodb-native driver.

    Parameters:

    • passed <Object> options that were passed directly during connection
    • [connStrOptions] <Object> options that were passed in the connection string

    NOTE: passed options take precedence over connection string options.

    show code

    1. NativeConnection.prototype.parseOptions = function (passed, connStrOpts) {
    2. var o = passed || {};
    3. o.db || (o.db = {});
    4. o.auth || (o.auth = {});
    5. o.server || (o.server = {});
    6. o.replset || (o.replset = {});
    7. o.server.socketOptions || (o.server.socketOptions = {});
    8. o.replset.socketOptions || (o.replset.socketOptions = {});
    9. var opts = connStrOpts || {};
    10. Object.keys(opts).forEach(function (name) {
    11. switch (name) {
    12. case 'ssl':
    13. case 'poolSize':
    14. if ('undefined' == typeof o.server[name]) {
    15. o.server[name] = o.replset[name] = opts[name];
    16. }
    17. break;
    18. case 'slaveOk':
    19. if ('undefined' == typeof o.server.slave_ok) {
    20. o.server.slave_ok = opts[name];
    21. }
    22. break;
    23. case 'autoReconnect':
    24. if ('undefined' == typeof o.server.auto_reconnect) {
    25. o.server.auto_reconnect = opts[name];
    26. }
    27. break;
    28. case 'socketTimeoutMS':
    29. case 'connectTimeoutMS':
    30. if ('undefined' == typeof o.server.socketOptions[name]) {
    31. o.server.socketOptions[name] = o.replset.socketOptions[name] = opts[name];
    32. }
    33. break;
    34. case 'authdb':
    35. if ('undefined' == typeof o.auth.authdb) {
    36. o.auth.authdb = opts[name];
    37. }
    38. break;
    39. case 'authSource':
    40. if ('undefined' == typeof o.auth.authSource) {
    41. o.auth.authSource = opts[name];
    42. }
    43. break;
    44. case 'retries':
    45. case 'reconnectWait':
    46. case 'rs_name':
    47. if ('undefined' == typeof o.replset[name]) {
    48. o.replset[name] = opts[name];
    49. }
    50. break;
    51. case 'replicaSet':
    52. if ('undefined' == typeof o.replset.rs_name) {
    53. o.replset.rs_name = opts[name];
    54. }
    55. break;
    56. case 'readSecondary':
    57. if ('undefined' == typeof o.replset.read_secondary) {
    58. o.replset.read_secondary = opts[name];
    59. }
    60. break;
    61. case 'nativeParser':
    62. if ('undefined' == typeof o.db.native_parser) {
    63. o.db.native_parser = opts[name];
    64. }
    65. break;
    66. case 'w':
    67. case 'safe':
    68. case 'fsync':
    69. case 'journal':
    70. case 'wtimeoutMS':
    71. if ('undefined' == typeof o.db[name]) {
    72. o.db[name] = opts[name];
    73. }
    74. break;
    75. case 'readPreference':
    76. if ('undefined' == typeof o.db.read_preference) {
    77. o.db.read_preference = opts[name];
    78. }
    79. break;
    80. case 'readPreferenceTags':
    81. if ('undefined' == typeof o.db.read_preference_tags) {
    82. o.db.read_preference_tags = opts[name];
    83. }
    84. break;
    85. }
    86. })
    87. if (!('auto_reconnect' in o.server)) {
    88. o.server.auto_reconnect = true;
    89. }
    90. if (!o.db.read_preference) {
    91. // read from primaries by default
    92. o.db.read_preference = 'primary';
    93. }
    94. // mongoose creates its own ObjectIds
    95. o.db.forceServerObjectId = false;
    96. // default safe using new nomenclature
    97. if (!('journal' in o.db || 'j' in o.db ||
    98. 'fsync' in o.db || 'safe' in o.db || 'w' in o.db)) {
    99. o.db.w = 1;
    100. }
    101. validate(o);
    102. return o;
    103. }

    NativeConnection#useDb(name)

    Switches to a different database using the same connection pool.

    Parameters:

    • name <String> The database name

    Returns:

    Returns a new connection object, with the new db.

    show code

    1. NativeConnection.prototype.useDb = function (name) {
    2. // we have to manually copy all of the attributes...
    3. var newConn = new this.constructor();
    4. newConn.name = name;
    5. newConn.base = this.base;
    6. newConn.collections = {};
    7. newConn.models = {};
    8. newConn.replica = this.replica;
    9. newConn.hosts = this.hosts;
    10. newConn.host = this.host;
    11. newConn.port = this.port;
    12. newConn.user = this.user;
    13. newConn.pass = this.pass;
    14. newConn.options = this.options;
    15. newConn._readyState = this._readyState;
    16. newConn._closeCalled = this._closeCalled;
    17. newConn._hasOpened = this._hasOpened;
    18. newConn._listening = false;
    19. // First, when we create another db object, we are not guaranteed to have a
    20. // db object to work with. So, in the case where we have a db object and it
    21. // is connected, we can just proceed with setting everything up. However, if
    22. // we do not have a db or the state is not connected, then we need to wait on
    23. // the 'open' event of the connection before doing the rest of the setup
    24. // the 'connected' event is the first time we'll have access to the db object
    25. var self = this;
    26. if (this.db && this.db._state == 'connected') {
    27. wireup();
    28. } else {
    29. this.once('connected', wireup);
    30. }
    31. function wireup () {
    32. newConn.db = self.db.db(name);
    33. newConn.onOpen();
    34. // setup the events appropriately
    35. listen(newConn);
    36. }
    37. newConn.name = name;
    38. // push onto the otherDbs stack, this is used when state changes
    39. this.otherDbs.push(newConn);
    40. newConn.otherDbs.push(this);
    41. return newConn;
    42. };

    NativeConnection.STATES

    Expose the possible connection states.

    show code

    1. NativeConnection.STATES = STATES;

  • error/version.js

    VersionError()

    Version Error constructor.

    Inherits:

    show code

    1. function VersionError () {
    2. MongooseError.call(this, 'No matching document found.');
    3. Error.captureStackTrace(this, arguments.callee);
    4. this.name = 'VersionError';
    5. };

  • error/messages.js

    MongooseError#messages

    The default built-in validator error messages. These may be customized.

    1. // customize within each schema or globally like so
    2. var mongoose = require('mongoose');
    3. mongoose.Error.messages.String.enum = "Your custom message for {PATH}.";

    As you might have noticed, error messages support basic templating

    • {PATH} is replaced with the invalid document path
    • {VALUE} is replaced with the invalid value
    • {TYPE} is replaced with the validator type such as “regexp”, “min”, or “user defined”
    • {MIN} is replaced with the declared min value for the Number.min validator
    • {MAX} is replaced with the declared max value for the Number.max validator

    Click the “show code” link below to see all defaults.

    show code

    1. var msg = module.exports = exports = {};
    2. msg.general = {};
    3. msg.general.default = "Validator failed for path `{PATH}` with value `{VALUE}`";
    4. msg.general.required = "Path `{PATH}` is required.";
    5. msg.Number = {};
    6. msg.Number.min = "Path `{PATH}` ({VALUE}) is less than minimum allowed value ({MIN}).";
    7. msg.Number.max = "Path `{PATH}` ({VALUE}) is more than maximum allowed value ({MAX}).";
    8. msg.String = {};
    9. msg.String.enum = "`{VALUE}` is not a valid enum value for path `{PATH}`.";
    10. msg.String.match = "Path `{PATH}` is invalid ({VALUE}).";

  • error/validation.js

    ValidationError#toString()

    Console.log helper

    show code

    1. ValidationError.prototype.toString = function () {
    2. var ret = this.name + ': ';
    3. var msgs = [];
    4. Object.keys(this.errors).forEach(function (key) {
    5. if (this == this.errors[key]) return;
    6. msgs.push(String(this.errors[key]));
    7. }, this)
    8. return ret + msgs.join(', ');
    9. };

    ValidationError(instance)

    Document Validation Error

    Parameters:

    Inherits:

    show code

    1. function ValidationError (instance) {
    2. MongooseError.call(this, "Validation failed");
    3. Error.captureStackTrace(this, arguments.callee);
    4. this.name = 'ValidationError';
    5. this.errors = instance.errors = {};
    6. };

  • error/cast.js

    CastError(type, value)

    Casting Error constructor.

    Parameters:

    Inherits:

    show code

    1. function CastError (type, value, path) {
    2. MongooseError.call(this, 'Cast to ' + type + ' failed for value "' + value + '" at path "' + path + '"');
    3. Error.captureStackTrace(this, arguments.callee);
    4. this.name = 'CastError';
    5. this.type = type;
    6. this.value = value;
    7. this.path = path;
    8. };

  • error/validator.js

    ValidatorError(path, msg, val)

    Schema validator error

    Parameters:

    Inherits:

    show code

    1. function ValidatorError (path, msg, type, val) {
    2. if (!msg) msg = errorMessages.general.default;
    3. var message = this.formatMessage(msg, path, type, val);
    4. MongooseError.call(this, message);
    5. Error.captureStackTrace(this, arguments.callee);
    6. this.name = 'ValidatorError';
    7. this.path = path;
    8. this.type = type;
    9. this.value = val;
    10. };

  • error.js

    MongooseError(msg)

    MongooseError constructor

    Parameters:

    Inherits:

    show code

    1. function MongooseError (msg) {
    2. Error.call(this);
    3. Error.captureStackTrace(this, arguments.callee);
    4. this.message = msg;
    5. this.name = 'MongooseError';
    6. };

    MongooseError.messages

    The default built-in validator error messages.

    show code

    1. MongooseError.messages = require('./error/messages');
    2. // backward compat
    3. MongooseError.Messages = MongooseError.messages;

    See:


  • virtualtype.js

    VirtualType#applyGetters(value, scope)

    Applies getters to value using optional scope.

    Parameters:

    Returns:

    • <T> the value after applying all getters

    show code

    1. VirtualType.prototype.applyGetters = function (value, scope) {
    2. var v = value;
    3. for (var l = this.getters.length - 1; l >= 0; l--) {
    4. v = this.getters[l].call(scope, v, this);
    5. }
    6. return v;
    7. };

    VirtualType#applySetters(value, scope)

    Applies setters to value using optional scope.

    Parameters:

    Returns:

    • <T> the value after applying all setters

    show code

    1. VirtualType.prototype.applySetters = function (value, scope) {
    2. var v = value;
    3. for (var l = this.setters.length - 1; l >= 0; l--) {
    4. v = this.setters[l].call(scope, v, this);
    5. }
    6. return v;
    7. };

    VirtualType#get(fn)

    Defines a getter.

    Parameters:

    Returns:

    Example:

    1. var virtual = schema.virtual('fullname');
    2. virtual.get(function () {
    3. return this.name.first + ' ' + this.name.last;
    4. });

    show code

    1. VirtualType.prototype.get = function (fn) {
    2. this.getters.push(fn);
    3. return this;
    4. };

    VirtualType#set(fn)

    Defines a setter.

    Parameters:

    Returns:

    Example:

    1. var virtual = schema.virtual('fullname');
    2. virtual.set(function (v) {
    3. var parts = v.split(' ');
    4. this.name.first = parts[0];
    5. this.name.last = parts[1];
    6. });

    show code

    1. VirtualType.prototype.set = function (fn) {
    2. this.setters.push(fn);
    3. return this;
    4. };

    VirtualType()

    VirtualType constructor

    This is what mongoose uses to define virtual attributes via Schema.prototype.virtual.

    Example:

    1. var fullname = schema.virtual('fullname');
    2. fullname instanceof mongoose.VirtualType // true

    show code

    1. function VirtualType (options, name) {
    2. this.path = name;
    3. this.getters = [];
    4. this.setters = [];
    5. this.options = options || {};
    6. }

  • schema.js

    Schema#add(obj, prefix)

    Adds key path / schema type pairs to this schema.

    Parameters:

    Example:

    1. var ToySchema = new Schema;
    2. ToySchema.add({ name: 'string', color: 'string', price: 'number' });

    show code

    1. Schema.prototype.add = function add (obj, prefix) {
    2. prefix = prefix || '';
    3. var keys = Object.keys(obj);
    4. for (var i = 0; i < keys.length; ++i) {
    5. var key = keys[i];
    6. if (null == obj[key]) {
    7. throw new TypeError('Invalid value for schema path `'+ prefix + key +'`');
    8. }
    9. if (utils.isObject(obj[key]) && (!obj[key].constructor || 'Object' == obj[key].constructor.name) && (!obj[key].type || obj[key].type.type)) {
    10. if (Object.keys(obj[key]).length) {
    11. // nested object { last: { name: String }}
    12. this.nested[prefix + key] = true;
    13. this.add(obj[key], prefix + key + '.');
    14. } else {
    15. this.path(prefix + key, obj[key]); // mixed type
    16. }
    17. } else {
    18. this.path(prefix + key, obj[key]);
    19. }
    20. }
    21. };

    Schema#defaultOptions(options)

    Returns default options for this schema, merged with options.

    Parameters:

    Returns:

    show code

    1. Schema.prototype.defaultOptions = function (options) {
    2. if (options && false === options.safe) {
    3. options.safe = { w: 0 };
    4. }
    5. if (options && options.safe && 0 === options.safe.w) {
    6. // if you turn off safe writes, then versioning goes off as well
    7. options.versionKey = false;
    8. }
    9. options = utils.options({
    10. strict: true
    11. , bufferCommands: true
    12. , capped: false // { size, max, autoIndexId }
    13. , versionKey: '__v'
    14. , discriminatorKey: '__t'
    15. , minimize: true
    16. , autoIndex: true
    17. , shardKey: null
    18. , read: null
    19. // the following are only applied at construction time
    20. , noId: false // deprecated, use { _id: false }
    21. , _id: true
    22. , noVirtualId: false // deprecated, use { id: false }
    23. , id: true
    24. // , pluralization: true // only set this to override the global option
    25. }, options);
    26. if (options.read) {
    27. options.read = utils.readPref(options.read);
    28. }
    29. return options;
    30. }

    Schema#eachPath(fn)

    Iterates the schemas paths similar to Array#forEach.

    Parameters:

    Returns:

    The callback is passed the pathname and schemaType as arguments on each iteration.

    show code

    1. Schema.prototype.eachPath = function (fn) {
    2. var keys = Object.keys(this.paths)
    3. , len = keys.length;
    4. for (var i = 0; i < len; ++i) {
    5. fn(keys[i], this.paths[keys[i]]);
    6. }
    7. return this;
    8. };

    Schema#get(key)

    Gets a schema option.

    Parameters:

    show code

    1. Schema.prototype.get = function (key) {
    2. return this.options[key];
    3. }

    Schema#index(fields, [options])

    Defines an index (most likely compound) for this schema.

    Parameters:

    Example

    1. schema.index({ first: 1, last: -1 })

    show code

    1. Schema.prototype.index = function (fields, options) {
    2. options || (options = {});
    3. if (options.expires)
    4. utils.expires(options);
    5. this._indexes.push([fields, options]);
    6. return this;
    7. };

    Schema#indexedPaths()

    Returns indexes from fields and schema-level indexes (cached).

    Returns:

    show code

    1. Schema.prototype.indexedPaths = function indexedPaths () {
    2. if (this._indexedpaths) return this._indexedpaths;
    3. return this._indexedpaths = this.indexes();
    4. }

    Schema#indexes()

    Compiles indexes from fields and schema-level indexes

    show code

    1. Schema.prototype.indexes = function () {
    2. 'use strict';
    3. var indexes = [];
    4. var seenPrefix = {};
    5. var collectIndexes = function(schema, prefix) {
    6. if (seenPrefix[prefix]) {
    7. return;
    8. }
    9. seenPrefix[prefix] = true;
    10. prefix = prefix || '';
    11. var key, path, index, field, isObject, options, type;
    12. var keys = Object.keys(schema.paths);
    13. for (var i = 0; i < keys.length; ++i) {
    14. key = keys[i];
    15. path = schema.paths[key];
    16. if (path instanceof Types.DocumentArray) {
    17. collectIndexes(path.schema, key + '.');
    18. } else {
    19. index = path._index;
    20. if (false !== index && null != index) {
    21. field = {};
    22. isObject = utils.isObject(index);
    23. options = isObject ? index : {};
    24. type = 'string' == typeof index ? index :
    25. isObject ? index.type :
    26. false;
    27. if (type && ~Schema.indexTypes.indexOf(type)) {
    28. field[prefix + key] = type;
    29. } else {
    30. field[prefix + key] = 1;
    31. }
    32. delete options.type;
    33. if (!('background' in options)) {
    34. options.background = true;
    35. }
    36. indexes.push([field, options]);
    37. }
    38. }
    39. }
    40. if (prefix) {
    41. fixSubIndexPaths(schema, prefix);
    42. } else {
    43. schema._indexes.forEach(function (index) {
    44. if (!('background' in index[1])) index[1].background = true;
    45. });
    46. indexes = indexes.concat(schema._indexes);
    47. }
    48. };
    49. collectIndexes(this);
    50. return indexes;

    Schema#method(method, [fn])

    Adds an instance method to documents constructed from Models compiled from this schema.

    Parameters:

    Example

    1. var schema = kittySchema = new Schema(..);
    2. schema.method('meow', function () {
    3. console.log('meeeeeoooooooooooow');
    4. })
    5. var Kitty = mongoose.model('Kitty', schema);
    6. var fizz = new Kitty;
    7. fizz.meow(); // meeeeeooooooooooooow

    If a hash of name/fn pairs is passed as the only argument, each name/fn pair will be added as methods.

    1. schema.method({
    2. purr: function () {}
    3. , scratch: function () {}
    4. });
    5. // later
    6. fizz.purr();
    7. fizz.scratch();

    show code

    1. Schema.prototype.method = function (name, fn) {
    2. if ('string' != typeof name)
    3. for (var i in name)
    4. this.methods[i] = name[i];
    5. else
    6. this.methods[name] = fn;
    7. return this;
    8. };

    Schema#path(path, constructor)

    Gets/sets schema paths.

    Parameters:

    Sets a path (if arity 2)
    Gets a path (if arity 1)

    Example

    1. schema.path('name') // returns a SchemaType
    2. schema.path('name', Number) // changes the schemaType of `name` to Number

    show code

    1. Schema.prototype.path = function (path, obj) {
    2. if (obj == undefined) {
    3. if (this.paths[path]) return this.paths[path];
    4. if (this.subpaths[path]) return this.subpaths[path];
    5. // subpaths?
    6. return /\.\d+\.?.*$/.test(path)
    7. ? getPositionalPath(this, path)
    8. : undefined;
    9. }
    10. // some path names conflict with document methods
    11. if (reserved[path]) {
    12. throw new Error("`" + path + "` may not be used as a schema pathname");
    13. }
    14. // update the tree
    15. var subpaths = path.split(/\./)
    16. , last = subpaths.pop()
    17. , branch = this.tree;
    18. subpaths.forEach(function(sub, i) {
    19. if (!branch[sub]) branch[sub] = {};
    20. if ('object' != typeof branch[sub]) {
    21. var msg = 'Cannot set nested path `' + path + '`. '
    22. + 'Parent path `'
    23. + subpaths.slice(0, i).concat([sub]).join('.')
    24. + '` already set to type ' + branch[sub].name
    25. + '.';
    26. throw new Error(msg);
    27. }
    28. branch = branch[sub];
    29. });
    30. branch[last] = utils.clone(obj);
    31. this.paths[path] = Schema.interpretAsType(path, obj, this.options);
    32. return this;
    33. };

    Schema#pathType(path)

    Returns the pathType of path for this schema.

    Parameters:

    Returns:

    Given a path, returns whether it is a real, virtual, nested, or ad-hoc/undefined path.

    show code

    1. Schema.prototype.pathType = function (path) {
    2. if (path in this.paths) return 'real';
    3. if (path in this.virtuals) return 'virtual';
    4. if (path in this.nested) return 'nested';
    5. if (path in this.subpaths) return 'real';
    6. if (/\.\d+\.|\.\d+$/.test(path) && getPositionalPath(this, path)) {
    7. return 'real';
    8. } else {
    9. return 'adhocOrUndefined'
    10. }
    11. };

    Schema#plugin(plugin, opts)

    Registers a plugin for this schema.

    Parameters:

    See:

    show code

    1. Schema.prototype.plugin = function (fn, opts) {
    2. fn(this, opts);
    3. return this;
    4. };

    Schema#post(method, fn)

    Defines a post hook for the document

    Parameters:

    See:

    Post hooks fire on the event emitted from document instances of Models compiled from this schema.

    1. var schema = new Schema(..);
    2. schema.post('save', function (doc) {
    3. console.log('this fired after a document was saved');
    4. });
    5. var Model = mongoose.model('Model', schema);
    6. var m = new Model(..);
    7. m.save(function (err) {
    8. console.log('this fires after the `post` hook');
    9. });

    show code

    1. Schema.prototype.post = function(method, fn){
    2. return this.queue('on', arguments);
    3. };

    Schema#pre(method, callback)

    Defines a pre hook for the document.

    Parameters:

    See:

    Example

    1. var toySchema = new Schema(..);
    2. toySchema.pre('save', function (next) {
    3. if (!this.created) this.created = new Date;
    4. next();
    5. })
    6. toySchema.pre('validate', function (next) {
    7. if (this.name != 'Woody') this.name = 'Woody';
    8. next();
    9. })

    show code

    1. Schema.prototype.pre = function(){
    2. return this.queue('pre', arguments);
    3. };

    Schema#queue(name, args)

    Adds a method call to the queue.

    Parameters:

    • name <String> name of the document method to call later
    • args <Array> arguments to pass to the method

    show code

    1. Schema.prototype.queue = function(name, args){
    2. this.callQueue.push([name, args]);
    3. return this;
    4. };

    Schema#requiredPaths()

    Returns an Array of path strings that are required by this schema.

    Returns:

    show code

    1. Schema.prototype.requiredPaths = function requiredPaths () {
    2. if (this._requiredpaths) return this._requiredpaths;
    3. var paths = Object.keys(this.paths)
    4. , i = paths.length
    5. , ret = [];
    6. while (i--) {
    7. var path = paths[i];
    8. if (this.paths[path].isRequired) ret.push(path);
    9. }
    10. return this._requiredpaths = ret;
    11. }

    Schema(definition)

    Schema constructor.

    Parameters:

    Inherits:

    Events:

    • init: Emitted after the schema is compiled into a Model.

    Example:

    1. var child = new Schema({ name: String });
    2. var schema = new Schema({ name: String, age: Number, children: [child] });
    3. var Tree = mongoose.model('Tree', schema);
    4. // setting schema options
    5. new Schema({ name: String }, { _id: false, autoIndex: false })

    Options:

    Note:

    When nesting schemas, (children in the example above), always declare the child schema first before passing it into is parent.

    show code

    1. function Schema (obj, options) {
    2. if (!(this instanceof Schema))
    3. return new Schema(obj, options);
    4. this.paths = {};
    5. this.subpaths = {};
    6. this.virtuals = {};
    7. this.nested = {};
    8. this.inherits = {};
    9. this.callQueue = [];
    10. this._indexes = [];
    11. this.methods = {};
    12. this.statics = {};
    13. this.tree = {};
    14. this._requiredpaths = undefined;
    15. this.discriminatorMapping = undefined;
    16. this._indexedpaths = undefined;
    17. this.options = this.defaultOptions(options);
    18. // build paths
    19. if (obj) {
    20. this.add(obj);
    21. }
    22. // ensure the documents get an auto _id unless disabled
    23. var auto_id = !this.paths['_id'] && (!this.options.noId && this.options._id);
    24. if (auto_id) {
    25. this.add({ _id: {type: Schema.ObjectId, auto: true} });
    26. }
    27. // ensure the documents receive an id getter unless disabled
    28. var autoid = !this.paths['id'] && (!this.options.noVirtualId && this.options.id);
    29. if (autoid) {
    30. this.virtual('id').get(idGetter);
    31. }
    32. }

    Schema#set(key, [value])

    Sets/gets a schema option.

    Parameters:

    • key <String> option name
    • [value] <Object> if not passed, the current option value is returned

    show code

    1. Schema.prototype.set = function (key, value, _tags) {
    2. if (1 === arguments.length) {
    3. return this.options[key];
    4. }
    5. switch (key) {
    6. case 'read':
    7. this.options[key] = utils.readPref(value, _tags)
    8. break;
    9. case 'safe':
    10. this.options[key] = false === value
    11. ? { w: 0 }
    12. : value
    13. break;
    14. default:
    15. this.options[key] = value;
    16. }
    17. return this;
    18. }

    Schema#static(name, fn)

    Adds static “class” methods to Models compiled from this schema.

    Parameters:

    Example

    1. var schema = new Schema(..);
    2. schema.static('findByName', function (name, callback) {
    3. return this.find({ name: name }, callback);
    4. });
    5. var Drink = mongoose.model('Drink', schema);
    6. Drink.findByName('sanpellegrino', function (err, drinks) {
    7. //
    8. });

    If a hash of name/fn pairs is passed as the only argument, each name/fn pair will be added as statics.

    show code

    1. Schema.prototype.static = function(name, fn) {
    2. if ('string' != typeof name)
    3. for (var i in name)
    4. this.statics[i] = name[i];
    5. else
    6. this.statics[name] = fn;
    7. return this;
    8. };

    Schema#virtual(name, [options])

    Creates a virtual type with the given name.

    Parameters:

    Returns:

    show code

    1. Schema.prototype.virtual = function (name, options) {
    2. var virtuals = this.virtuals;
    3. var parts = name.split('.');
    4. return virtuals[name] = parts.reduce(function (mem, part, i) {
    5. mem[part] || (mem[part] = (i === parts.length-1)
    6. ? new VirtualType(options, name)
    7. : {});
    8. return mem[part];
    9. }, this.tree);
    10. };

    Schema#virtualpath(name)

    Returns the virtual type with the given name.

    Parameters:

    Returns:

    show code

    1. Schema.prototype.virtualpath = function (name) {
    2. return this.virtuals[name];
    3. };

    Schema.indexTypes()

    The allowed index types

    show code

    1. var indexTypes = '2d 2dsphere hashed text'.split(' ');
    2. Object.defineProperty(Schema, 'indexTypes', {
    3. get: function () { return indexTypes }
    4. , set: function () { throw new Error('Cannot overwrite Schema.indexTypes') }
    5. })

    Schema.interpretAsType(path, obj)

    Converts type arguments into Mongoose Types.

    show code

    1. Schema.interpretAsType = function (path, obj, options) {
    2. if (obj.constructor && obj.constructor.name != 'Object')
    3. obj = { type: obj };
    4. // Get the type making sure to allow keys named "type"
    5. // and default to mixed if not specified.
    6. // { type: { type: String, default: 'freshcut' } }
    7. var type = obj.type && !obj.type.type
    8. ? obj.type
    9. : {};
    10. if ('Object' == type.constructor.name || 'mixed' == type) {
    11. return new Types.Mixed(path, obj);
    12. }
    13. if (Array.isArray(type) || Array == type || 'array' == type) {
    14. // if it was specified through { type } look for `cast`
    15. var cast = (Array == type || 'array' == type)
    16. ? obj.cast
    17. : type[0];
    18. if (cast instanceof Schema) {
    19. return new Types.DocumentArray(path, cast, obj);
    20. }
    21. if ('string' == typeof cast) {
    22. cast = Types[cast.charAt(0).toUpperCase() + cast.substring(1)];
    23. } else if (cast && (!cast.type || cast.type.type)
    24. && 'Object' == cast.constructor.name
    25. && Object.keys(cast).length) {
    26. return new Types.DocumentArray(path, new Schema(cast, options), obj);
    27. }
    28. return new Types.Array(path, cast || Types.Mixed, obj);
    29. }
    30. var name = 'string' == typeof type
    31. ? type
    32. : type.name;
    33. if (name) {
    34. name = name.charAt(0).toUpperCase() + name.substring(1);
    35. }
    36. if (undefined == Types[name]) {
    37. throw new TypeError('Undefined type at `' + path +
    38. '`
    39. Did you try nesting Schemas? ' +
    40. 'You can only nest using refs or arrays.');
    41. }
    42. return new Types[name](path, obj);
    43. };

    Parameters:


    Schema.reserved

    Reserved document keys.

    show code

    1. Schema.reserved = Object.create(null);
    2. var reserved = Schema.reserved;
    3. reserved.on =
    4. reserved.db =
    5. reserved.set =
    6. reserved.get =
    7. reserved.init =
    8. reserved.isNew =
    9. reserved.errors =
    10. reserved.schema =
    11. reserved.options =
    12. reserved.modelName =
    13. reserved.collection =
    14. reserved.toObject =
    15. reserved.emit = // EventEmitter
    16. reserved._events = // EventEmitter
    17. reserved._pres = reserved._posts = 1 // hooks.js

    Keys in this object are names that are rejected in schema declarations b/c they conflict with mongoose functionality. Using these key name will throw an error.

    1. on, emit, _events, db, get, set, init, isNew, errors, schema, options, modelName, collection, _pres, _posts, toObject

    NOTE: Use of these terms as method names is permitted, but play at your own risk, as they may be existing mongoose document methods you are stomping on.

    1. var schema = new Schema(..);
    2. schema.methods.init = function () {} // potentially breaking

    Schema.Types

    The various built-in Mongoose Schema Types.

    show code

    1. Schema.Types = require('./schema/index');

    Example:

    1. var mongoose = require('mongoose');
    2. var ObjectId = mongoose.Schema.Types.ObjectId;

    Types:

    Using this exposed access to the Mixed SchemaType, we can use them in our schema.

    1. var Mixed = mongoose.Schema.Types.Mixed;
    2. new mongoose.Schema({ _user: Mixed })

    Schema#paths

    Schema as flat paths

    Example:

    1. {
    2. '_id' : SchemaType,
    3. , 'nested.key' : SchemaType,
    4. }

    show code

    1. Schema.prototype.paths;

    Schema#tree

    Schema as a tree

    Example:

    1. {
    2. '_id' : ObjectId
    3. , 'nested' : {
    4. 'key' : String
    5. }
    6. }

    show code

    1. Schema.prototype.tree;

  • schemadefault.js

    exports#system.profile

    Default model for querying the system.profiles collection.

    show code

    1. exports['system.profile'] = new Schema({
    2. ts: Date
    3. , info: String // deprecated
    4. , millis: Number
    5. , op: String
    6. , ns: String
    7. , query: Schema.Types.Mixed
    8. , updateobj: Schema.Types.Mixed
    9. , ntoreturn: Number
    10. , nreturned: Number
    11. , nscanned: Number
    12. , responseLength: Number
    13. , client: String
    14. , user: String
    15. , idhack: Boolean
    16. , scanAndOrder: Boolean
    17. , keyUpdates: Number
    18. , cursorid: Number
    19. }, { noVirtualId: true, noId: true });

  • document.js

    Document#$__buildDoc(obj, [fields], [skipId])

    Builds the default doc structure

    Parameters:

    Returns:


    Document#$__dirty()

    Returns this documents dirty paths / vals.


    Document#$__doQueue()

    Executes methods queued from the Schema definition


    Document#$__error(err)

    Registers an error

    Parameters:


    Document#$__fullPath([path])

    Returns the full path to this document.

    Parameters:

    Returns:


    Document#$__path(path)

    Returns the schematype for the given path.

    Parameters:


    Document#$__registerHooks()

    Register default hooks


    Document#$__reset()

    Resets the internal modified state of this document.

    Returns:


    Document#$__set()

    Handles the actual setting of the value and marking the path modified if appropriate.


    Document#$__setSchema(schema)

    Assigns/compiles schema into this documents prototype.

    Parameters:


    Document#$__shouldModify()

    Determine if we should mark this change as modified.

    Returns:


    Document#$__storeShard()

    Stores the current values of the shard keys.

    Note:

    Shard key values do not / are not allowed to change.


    Document#$__try(fn, scope)

    Catches errors that occur during execution of fn and stores them to later be passed when save() is executed.

    Parameters:

    • fn <Function> function to execute
    • scope <Object> the scope with which to call fn

    Document#$toObject()

    Internal helper for toObject() and toJSON() that doesn’t manipulate options


    Document(obj, [opts], [skipId])

    Document constructor.

    Parameters:

    • obj <Object> the values to set
    • [opts] <Object> optional object containing the fields which were selected in the query returning this document and any populated paths data
    • [skipId] <Boolean> bool, should we auto create an ObjectId _id

    Inherits:

    Events:

    • init: Emitted on a document after it has was retreived from the db and fully hydrated by Mongoose.

    • save: Emitted when the document is successfully saved

    show code

    1. function Document (obj, fields, skipId) {
    2. this.$__ = new InternalCache;
    3. this.isNew = true;
    4. this.errors = undefined;
    5. var schema = this.schema;
    6. if ('boolean' === typeof fields) {
    7. this.$__.strictMode = fields;
    8. fields = undefined;
    9. } else {
    10. this.$__.strictMode = schema.options && schema.options.strict;
    11. this.$__.selected = fields;
    12. }
    13. var required = schema.requiredPaths();
    14. for (var i = 0; i < required.length; ++i) {
    15. this.$__.activePaths.require(required[i]);
    16. }
    17. setMaxListeners.call(this, 0);
    18. this._doc = this.$__buildDoc(obj, fields, skipId);
    19. if (obj) {
    20. this.set(obj, undefined, true);
    21. }
    22. this.$__registerHooks();
    23. }

    Document#equals(doc)

    Returns true if the Document stores the same data as doc.

    Parameters:

    Returns:

    Documents are considered equal when they have matching _ids, unless neither
    document has an _id, in which case this function falls back to using
    deepEqual().

    show code

    1. Document.prototype.equals = function (doc) {
    2. var tid = this.get('_id');
    3. var docid = doc.get('_id');
    4. if (!tid && !docid) {
    5. return deepEqual(this, doc);
    6. }
    7. return tid && tid.equals
    8. ? tid.equals(docid)
    9. : tid === docid;
    10. }

    Document#get(path, [type])

    Returns the value of a path.

    Parameters:

    Example

    1. // path
    2. doc.get('age') // 47
    3. // dynamic casting to a string
    4. doc.get('age', String) // "47"

    show code

    1. Document.prototype.get = function (path, type) {
    2. var adhocs;
    3. if (type) {
    4. adhocs = this.$__.adhocPaths || (this.$__.adhocPaths = {});
    5. adhocs[path] = Schema.interpretAsType(path, type);
    6. }
    7. var schema = this.$__path(path) || this.schema.virtualpath(path)
    8. , pieces = path.split('.')
    9. , obj = this._doc;
    10. for (var i = 0, l = pieces.length; i < l; i++) {
    11. obj = undefined === obj || null === obj
    12. ? undefined
    13. : obj[pieces[i]];
    14. }
    15. if (schema) {
    16. obj = schema.applyGetters(obj, this);
    17. }
    18. return obj;
    19. };

    Document#getValue(path)

    Gets a raw value from a path (no getters)

    Parameters:

    show code

    1. Document.prototype.getValue = function (path) {
    2. return utils.getValue(path, this._doc);
    3. }

    Document#init(doc, fn)

    Initializes the document without setters or marking anything modified.

    Parameters:

    Called internally after a document is returned from mongodb.

    show code

    1. Document.prototype.init = function (doc, opts, fn) {
    2. // do not prefix this method with $__ since its
    3. // used by public hooks
    4. if ('function' == typeof opts) {
    5. fn = opts;
    6. opts = null;
    7. }
    8. this.isNew = false;
    9. // handle docs with populated paths
    10. if (doc._id && opts && opts.populated && opts.populated.length) {
    11. var id = String(doc._id);
    12. for (var i = 0; i < opts.populated.length; ++i) {
    13. var item = opts.populated[i];
    14. this.populated(item.path, item._docs[id], item);
    15. }
    16. }
    17. init(this, doc, this._doc);
    18. this.$__storeShard();
    19. this.emit('init', this);
    20. if (fn) fn(null);
    21. return this;
    22. };

    Document#inspect()

    Helper for console.log

    show code

    1. Document.prototype.inspect = function (options) {
    2. var opts = options && 'Object' == options.constructor.name ? options :
    3. this.schema.options.toObject ? clone(this.schema.options.toObject) :
    4. {};
    5. opts.minimize = false;
    6. return inspect(this.toObject(opts));
    7. };

    Document#invalidate(path, errorMsg, value)

    Marks a path as invalid, causing validation to fail.

    Parameters:

    The errorMsg argument will become the message of the ValidationError.

    The value argument (if passed) will be available through the ValidationError.value property.

    1. doc.invalidate('size', 'must be less than 20', 14);
    2. doc.validate(function (err) {
    3. console.log(err)
    4. // prints
    5. { message: 'Validation failed',
    6. name: 'ValidationError',
    7. errors:
    8. { size:
    9. { message: 'must be less than 20',
    10. name: 'ValidatorError',
    11. path: 'size',
    12. type: 'user defined',
    13. value: 14 } } }
    14. })

    show code

    1. Document.prototype.invalidate = function (path, err, val) {
    2. if (!this.$__.validationError) {
    3. this.$__.validationError = new ValidationError(this);
    4. }
    5. if (!err || 'string' === typeof err) {
    6. err = new ValidatorError(path, err, 'user defined', val)
    7. }
    8. if (this.$__.validationError == err) return;
    9. this.$__.validationError.errors[path] = err;
    10. }

    Document#isDirectModified(path)

    Returns true if path was directly set and modified, else false.

    Parameters:

    Returns:

    Example

    1. doc.set('documents.0.title', 'changed');
    2. doc.isDirectModified('documents.0.title') // true
    3. doc.isDirectModified('documents') // false

    show code

    1. Document.prototype.isDirectModified = function (path) {
    2. return (path in this.$__.activePaths.states.modify);
    3. };

    Document#isInit(path)

    Checks if path was initialized.

    Parameters:

    Returns:

    show code

    1. Document.prototype.isInit = function (path) {
    2. return (path in this.$__.activePaths.states.init);
    3. };

    Document#isModified([path])

    Returns true if this document was modified, else false.

    Parameters:

    Returns:

    If path is given, checks if a path or any full path containing path as part of its path chain has been modified.

    Example

    1. doc.set('documents.0.title', 'changed');
    2. doc.isModified() // true
    3. doc.isModified('documents') // true
    4. doc.isModified('documents.0.title') // true
    5. doc.isDirectModified('documents') // false

    show code

    1. Document.prototype.isModified = function (path) {
    2. return path
    3. ? !!~this.modifiedPaths().indexOf(path)
    4. : this.$__.activePaths.some('modify');
    5. };

    Document#isSelected(path)

    Checks if path was selected in the source query which initialized this document.

    Parameters:

    Returns:

    Example

    1. Thing.findOne().select('name').exec(function (err, doc) {
    2. doc.isSelected('name') // true
    3. doc.isSelected('age') // false
    4. })

    show code

    1. Document.prototype.isSelected = function isSelected (path) {
    2. if (this.$__.selected) {
    3. if ('_id' === path) {
    4. return 0 !== this.$__.selected._id;
    5. }
    6. var paths = Object.keys(this.$__.selected)
    7. , i = paths.length
    8. , inclusive = false
    9. , cur
    10. if (1 === i && '_id' === paths[0]) {
    11. // only _id was selected.
    12. return 0 === this.$__.selected._id;
    13. }
    14. while (i--) {
    15. cur = paths[i];
    16. if ('_id' == cur) continue;
    17. inclusive = !! this.$__.selected[cur];
    18. break;
    19. }
    20. if (path in this.$__.selected) {
    21. return inclusive;
    22. }
    23. i = paths.length;
    24. var pathDot = path + '.';
    25. while (i--) {
    26. cur = paths[i];
    27. if ('_id' == cur) continue;
    28. if (0 === cur.indexOf(pathDot)) {
    29. return inclusive;
    30. }
    31. if (0 === pathDot.indexOf(cur + '.')) {
    32. return inclusive;
    33. }
    34. }
    35. return ! inclusive;
    36. }
    37. return true;
    38. }

    Document#markModified(path)

    Marks the path as having pending changes to write to the db.

    Parameters:

    • path <String> the path to mark modified

    Very helpful when using Mixed types.

    Example:

    1. doc.mixed.type = 'changed';
    2. doc.markModified('mixed.type');
    3. doc.save() // changes to mixed.type are now persisted

    show code

    1. Document.prototype.markModified = function (path) {
    2. this.$__.activePaths.modify(path);
    3. }

    Document#modifiedPaths()

    Returns the list of paths that have been modified.

    Returns:

    show code

    1. Document.prototype.modifiedPaths = function () {
    2. var directModifiedPaths = Object.keys(this.$__.activePaths.states.modify);
    3. return directModifiedPaths.reduce(function (list, path) {
    4. var parts = path.split('.');
    5. return list.concat(parts.reduce(function (chains, part, i) {
    6. return chains.concat(parts.slice(0, i).concat(part).join('.'));
    7. }, []));
    8. }, []);
    9. };

    Document#populate([path], [callback])

    Populates document references, executing the callback when complete.

    Parameters:

    • [path] <String, Object> The path to populate or an options object
    • [callback] <Function> When passed, population is invoked

    Returns:

    See:

    Example:

    1. doc
    2. .populate('company')
    3. .populate({
    4. path: 'notes',
    5. match: /airline/,
    6. select: 'text',
    7. model: 'modelName'
    8. options: opts
    9. }, function (err, user) {
    10. assert(doc._id == user._id) // the document itself is passed
    11. })
    12. // summary
    13. doc.populate(path) // not executed
    14. doc.populate(options); // not executed
    15. doc.populate(path, callback) // executed
    16. doc.populate(options, callback); // executed
    17. doc.populate(callback); // executed

    NOTE:

    Population does not occur unless a callback is passed.
    Passing the same path a second time will overwrite the previous path options.
    See Model.populate() for explaination of options.

    show code

    1. Document.prototype.populate = function populate () {
    2. if (0 === arguments.length) return this;
    3. var pop = this.$__.populate || (this.$__.populate = {});
    4. var args = utils.args(arguments);
    5. var fn;
    6. if ('function' == typeof args[args.length-1]) {
    7. fn = args.pop();
    8. }
    9. // allow `doc.populate(callback)`
    10. if (args.length) {
    11. // use hash to remove duplicate paths
    12. var res = utils.populate.apply(null, args);
    13. for (var i = 0; i < res.length; ++i) {
    14. pop[res[i].path] = res[i];
    15. }
    16. }
    17. if (fn) {
    18. var paths = utils.object.vals(pop);
    19. this.$__.populate = undefined;
    20. this.constructor.populate(this, paths, fn);
    21. }
    22. return this;
    23. }

    Document#populated(path)

    Gets _id(s) used during population of the given path.

    Parameters:

    Returns:

    Example:

    1. Model.findOne().populate('author').exec(function (err, doc) {
    2. console.log(doc.author.name) // Dr.Seuss
    3. console.log(doc.populated('author')) // '5144cf8050f071d979c118a7'
    4. })

    If the path was not populated, undefined is returned.

    show code

    1. Document.prototype.populated = function (path, val, options) {
    2. // val and options are internal
    3. if (null == val) {
    4. if (!this.$__.populated) return undefined;
    5. var v = this.$__.populated[path];
    6. if (v) return v.value;
    7. return undefined;
    8. }
    9. // internal
    10. if (true === val) {
    11. if (!this.$__.populated) return undefined;
    12. return this.$__.populated[path];
    13. }
    14. this.$__.populated || (this.$__.populated = {});
    15. this.$__.populated[path] = { value: val, options: options };
    16. return val;
    17. }

    Document#set(path, val, [type], [options])

    Sets the value of a path, or many paths.

    Parameters:

    • path <String, Object> path or object of key/vals to set
    • val <Any> the value to set
    • [type] <Schema, String, Number, Buffer, etc..> optionally specify a type for “on-the-fly” attributes
    • [options] <Object> optionally specify options that modify the behavior of the set

    Example:

    1. // path, value
    2. doc.set(path, value)
    3. // object
    4. doc.set({
    5. path : value
    6. , path2 : {
    7. path : value
    8. }
    9. })
    10. // only-the-fly cast to number
    11. doc.set(path, value, Number)
    12. // only-the-fly cast to string
    13. doc.set(path, value, String)
    14. // changing strict mode behavior
    15. doc.set(path, value, { strict: false });

    show code

    ``` Document.prototype.set = function (path, val, type, options) { if (type && ‘Object’ == type.constructor.name) {

    1. options = type;
    2. type = undefined;

    }

    var merge = options && options.merge

    1. , adhoc = type && true !== type
    2. , constructing = true === type
    3. , adhocs

    var strict = options && ‘strict’ in options

    1. ? options.strict
    2. : this.$__.strictMode;

    if (adhoc) {

    1. adhocs = this.$__.adhocPaths || (this.$__.adhocPaths = {});
    2. adhocs[path] = Schema.interpretAsType(path, type);

    }

    if (‘string’ !== typeof path) {

    1. // new Document({ key: val })
    2. if (null === path || undefined === path) {
    3. var _ = path;
    4. path = val;
    5. val = _;
    6. } else {
    7. var prefix = val
    8. ? val + '.'
    9. : '';
    10. if (path instanceof Document) path = path._doc;
    11. var keys = Object.keys(path)
    12. , i = keys.length
    13. , pathtype
    14. , key
  1. while (i--) {
  2. key = keys[i];
  3. var pathName = prefix + key;
  4. pathtype = this.schema.pathType(pathName);
  5. if (null != path[key]
  6. // need to know if plain object - no Buffer, ObjectId, ref, etc
  7. && utils.isObject(path[key])
  8. && (!path[key].constructor || 'Object' == path[key].constructor.name)
  9. && 'virtual' != pathtype
  10. && !(this.$__path(pathName) instanceof MixedSchema)
  11. && !(this.schema.paths[pathName] &&
  12. this.schema.paths[pathName].options &&
  13. this.schema.paths[pathName].options.ref)) {
  14. this.set(path[key], prefix + key, constructing);
  15. } else if (strict) {
  16. if ('real' === pathtype || 'virtual' === pathtype) {
  17. this.set(prefix + key, path[key], constructing);
  18. } else if ('throw' == strict) {
  19. throw new Error('Field `' + key + '` is not in schema.');
  20. }
  21. } else if (undefined !== path[key]) {
  22. this.set(prefix + key, path[key], constructing);
  23. }
  24. }
  25. return this;
  26. }
  27. }
  28. // ensure _strict is honored for obj props
  29. // docschema = new Schema({ path: { nest: 'string' }})
  30. // doc.set('path', obj);
  31. var pathType = this.schema.pathType(path);
  32. if ('nested' == pathType && val && utils.isObject(val) &&
  33. (!val.constructor || 'Object' == val.constructor.name)) {
  34. if (!merge) this.setValue(path, null);
  35. this.set(val, path, constructing);
  36. return this;
  37. }
  38. var schema;
  39. var parts = path.split('.');
  40. if ('adhocOrUndefined' == pathType && strict) {
  41. // check for roots that are Mixed types
  42. var mixed;
  43. for (var i = 0; i < parts.length; ++i) {
  44. var subpath = parts.slice(0, i+1).join('.');
  45. schema = this.schema.path(subpath);
  46. if (schema instanceof MixedSchema) {
  47. // allow changes to sub paths of mixed types
  48. mixed = true;
  49. break;
  50. }
  51. }
  52. if (!mixed) {
  53. if ('throw' == strict) {
  54. throw new Error("Field `" + path + "` is not in schema.");
  55. }
  56. return this;
  57. }
  58. } else if ('virtual' == pathType) {
  59. schema = this.schema.virtualpath(path);
  60. schema.applySetters(val, this);
  61. return this;
  62. } else {
  63. schema = this.$__path(path);
  64. }
  65. var pathToMark;
  66. // When using the $set operator the path to the field must already exist.
  67. // Else mongodb throws: "LEFT_SUBFIELD only supports Object"
  68. if (parts.length <= 1) {
  69. pathToMark = path;
  70. } else {
  71. for (var i = 0; i < parts.length; ++i) {
  72. var subpath = parts.slice(0, i+1).join('.');
  73. if (this.isDirectModified(subpath) // earlier prefixes that are already
  74. // marked as dirty have precedence
  75. || this.get(subpath) === null) {
  76. pathToMark = subpath;
  77. break;
  78. }
  79. }
  80. if (!pathToMark) pathToMark = path;
  81. }
  82. // if this doc is being constructed we should not trigger getters
  83. var priorVal = constructing
  84. ? undefined
  85. : this.getValue(path);
  86. if (!schema || undefined === val) {
  87. this.$__set(pathToMark, path, constructing, parts, schema, val, priorVal);
  88. return this;
  89. }
  90. var self = this;
  91. var shouldSet = this.$__try(function(){
  92. val = schema.applySetters(val, self, false, priorVal);
  93. });
  94. if (shouldSet) {
  95. this.$__set(pathToMark, path, constructing, parts, schema, val, priorVal);
  96. }
  97. return this;
  98. }
  99. ```
  100. ---
  101. ### [Document#setValue(`path`, `value`)](#document_Document-setValue)
  102. Sets a raw value for a path (no casting, setters, transformations)
  103. #### Parameters:
  104. - `path` &lt;[String](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String)&gt;
  105. - `value` &lt;[Object](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object)&gt;
  106. show code
  107. ```
  108. Document.prototype.setValue = function (path, val) {
  109. utils.setValue(path, val, this._doc);
  110. return this;
  111. }
  112. ```
  113. ---
  114. ### [Document#toJSON(`options`)](#document_Document-toJSON)
  115. The return value of this method is used in calls to JSON.stringify(doc).
  116. #### Parameters:
  117. - `options` &lt;[Object](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object)&gt;
  118. #### Returns:
  119. - &lt;[Object](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object)&gt;
  120. #### See:
  121. - [Document#toObject](#document_Document-toObject "Document#toObject")
  122. This method accepts the same options as [Document#toObject](#document_Document-toObject). To apply the options to every document of your schema by default, set your [schemas](#schema_Schema) `toJSON` option to the same argument.
  123. ```
  124. schema.set('toJSON', { virtuals: true })
  125. ```
  126. See [schema options](https://mongoosejs.com/docs/guide.html#toJSON) for details.
  127. show code
  128. ```
  129. Document.prototype.toJSON = function (options) {
  130. if (options && options.depopulate && this.$__.wasPopulated) {
  131. // populated paths that we set to a document
  132. return clone(this._id, options);
  133. }
  134. // When internally saving this document we always pass options,
  135. // bypassing the custom schema options.
  136. var optionsParameter = options;
  137. if (!(options && 'Object' == options.constructor.name) ||
  138. (options && options._useSchemaOptions)) {
  139. options = this.schema.options.toJSON ?
  140. clone(this.schema.options.toJSON) :
  141. {};
  142. options._useSchemaOptions = true;
  143. }
  144. ;('minimize' in options) || (options.minimize = this.schema.options.minimize);
  145. options.json = true;
  146. return this.$toObject(options);
  147. };
  148. ```
  149. ---
  150. ### [Document#toObject(`[options]`)](#document_Document-toObject)
  151. Converts this document into a plain javascript object, ready for storage in MongoDB.
  152. #### Parameters:
  153. - `[options]` &lt;[Object](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object)&gt;
  154. #### Returns:
  155. - &lt;[Object](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object)&gt; js object
  156. #### See:
  157. - [mongodb.Binary](http://mongodb.github.com/node-mongodb-native/api-bson-generated/binary.html "mongodb.Binary")
  158. Buffers are converted to instances of [mongodb.Binary](http://mongodb.github.com/node-mongodb-native/api-bson-generated/binary.html) for proper storage.
  159. #### Options:
  160. - `getters` apply all getters (path and virtual getters)
  161. - `virtuals` apply virtual getters (can override `getters` option)
  162. - `minimize` remove empty objects (defaults to true)
  163. - `transform` a transform function to apply to the resulting document before returning
  164. - `depopulate` depopulate any populated paths, replacing them with their original refs (defaults to false)
  165. #### Getters/Virtuals
  166. Example of only applying path getters
  167. ```
  168. doc.toObject({ getters: true, virtuals: false })
  169. ```
  170. Example of only applying virtual getters
  171. ```
  172. doc.toObject({ virtuals: true })
  173. ```
  174. Example of applying both path and virtual getters
  175. ```
  176. doc.toObject({ getters: true })
  177. ```
  178. To apply these options to every document of your schema by default, set your [schemas](#schema_Schema) `toObject` option to the same argument.
  179. ```
  180. schema.set('toObject', { virtuals: true })
  181. ```
  182. #### Transform
  183. We may need to perform a transformation of the resulting object based on some criteria, say to remove some sensitive information or return a custom object. In this case we set the optional `transform` function.
  184. Transform functions receive three arguments
  185. ```
  186. function (doc, ret, options) {}
  187. ```
  188. - `doc` The mongoose document which is being converted
  189. - `ret` The plain object representation which has been converted
  190. - `options` The options in use (either schema options or the options passed inline)
  191. #### Example
  192. ```
  193. // specify the transform schema option
  194. if (!schema.options.toObject) schema.options.toObject = {};
  195. schema.options.toObject.transform = function (doc, ret, options) {
  196. // remove the _id of every document before returning the result
  197. delete ret._id;
  198. }
  199. // without the transformation in the schema
  200. doc.toObject(); // { _id: 'anId', name: 'Wreck-it Ralph' }
  201. // with the transformation
  202. doc.toObject(); // { name: 'Wreck-it Ralph' }
  203. ```
  204. With transformations we can do a lot more than remove properties. We can even return completely new customized objects:
  205. ```
  206. if (!schema.options.toObject) schema.options.toObject = {};
  207. schema.options.toObject.transform = function (doc, ret, options) {
  208. return { movie: ret.name }
  209. }
  210. // without the transformation in the schema
  211. doc.toObject(); // { _id: 'anId', name: 'Wreck-it Ralph' }
  212. // with the transformation
  213. doc.toObject(); // { movie: 'Wreck-it Ralph' }
  214. ```
  215. *Note: if a transform function returns `undefined`, the return value will be ignored.*
  216. Transformations may also be applied inline, overridding any transform set in the options:
  217. ```
  218. function xform (doc, ret, options) {
  219. return { inline: ret.name, custom: true }
  220. }
  221. // pass the transform as an inline option
  222. doc.toObject({ transform: xform }); // { inline: 'Wreck-it Ralph', custom: true }
  223. ```
  224. *Note: if you call `toObject` and pass any options, the transform declared in your schema options will **not** be applied. To force its application pass `transform: true`*
  225. ```
  226. if (!schema.options.toObject) schema.options.toObject = {};
  227. schema.options.toObject.hide = '_id';
  228. schema.options.toObject.transform = function (doc, ret, options) {
  229. if (options.hide) {
  230. options.hide.split(' ').forEach(function (prop) {
  231. delete ret[prop];
  232. });
  233. }
  234. }
  235. var doc = new Doc({ _id: 'anId', secret: 47, name: 'Wreck-it Ralph' });
  236. doc.toObject(); // { secret: 47, name: 'Wreck-it Ralph' }
  237. doc.toObject({ hide: 'secret _id' }); // { _id: 'anId', secret: 47, name: 'Wreck-it Ralph' }
  238. doc.toObject({ hide: 'secret _id', transform: true }); // { name: 'Wreck-it Ralph' }
  239. ```
  240. Transforms are applied to the document *and each of its sub-documents*. To determine whether or not you are currently operating on a sub-document you might use the following guard:
  241. ```
  242. if ('function' == typeof doc.ownerDocument) {
  243. // working with a sub doc
  244. }
  245. ```
  246. Transforms, like all of these options, are also available for `toJSON`.
  247. See [schema options](https://mongoosejs.com/docs/guide.html#toObject) for some more details.
  248. *During save, no custom options are applied to the document before being sent to the database.*
  249. show code
  250. ```
  251. Document.prototype.toObject = function (options) {
  252. if (options && options.depopulate && this.$__.wasPopulated) {
  253. // populated paths that we set to a document
  254. return clone(this._id, options);
  255. }
  256. // When internally saving this document we always pass options,
  257. // bypassing the custom schema options.
  258. var optionsParameter = options;
  259. if (!(options && 'Object' == options.constructor.name) ||
  260. (options && options._useSchemaOptions)) {
  261. options = this.schema.options.toObject ?
  262. clone(this.schema.options.toObject) :
  263. {};
  264. options._useSchemaOptions = true;
  265. }
  266. ;('minimize' in options) || (options.minimize = this.schema.options.minimize);
  267. return this.$toObject(options);
  268. };
  269. ```
  270. ---
  271. ### [Document#toString()](#document_Document-toString)
  272. Helper for console.log
  273. ---
  274. ### [Document#update(`doc`, `options`, `callback`)](#document_Document-update)
  275. Sends an update command with this document `_id` as the query selector.
  276. #### Parameters:
  277. - `doc` &lt;[Object](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object)&gt;
  278. - `options` &lt;[Object](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object)&gt;
  279. - `callback` &lt;[Function](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function)&gt;
  280. #### Returns:
  281. - &lt;[Query](#query-js)&gt;
  282. #### See:
  283. - [Model.update](#model_Model.update "Model.update")
  284. #### Example:
  285. ```
  286. weirdCar.update({$inc: {wheels:1}}, { w: 1 }, callback);
  287. ```
  288. #### Valid options:
  289. - same as in [Model.update](#model_Model.update)
  290. show code
  291. ```
  292. Document.prototype.update = function update () {
  293. var args = utils.args(arguments);
  294. args.unshift({_id: this._id});
  295. return this.constructor.update.apply(this.constructor, args);
  296. }
  297. ```
  298. ---
  299. ### [Document#validate(`cb`)](#document_Document-validate)
  300. Executes registered validation rules for this document.
  301. #### Parameters:
  302. - `cb` &lt;[Function](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function)&gt; called after validation completes, passing an error if one occurred
  303. #### Note:
  304. This method is called `pre` save and if a validation rule is violated, [save](#model_Model-save) is aborted and the error is returned to your `callback`.
  305. #### Example:
  306. ```
  307. doc.validate(function (err) {
  308. if (err) handleError(err);
  309. else // validation passed
  310. });
  311. ```
  312. show code
  313. ```
  314. Document.prototype.validate = function (cb) {
  315. var self = this
  316. // only validate required fields when necessary
  317. var paths = Object.keys(this.$__.activePaths.states.require).filter(function (path) {
  318. if (!self.isSelected(path) && !self.isModified(path)) return false;
  319. return true;
  320. });
  321. paths = paths.concat(Object.keys(this.$__.activePaths.states.init));
  322. paths = paths.concat(Object.keys(this.$__.activePaths.states.modify));
  323. paths = paths.concat(Object.keys(this.$__.activePaths.states.default));
  324. if (0 === paths.length) {
  325. complete();
  326. return this;
  327. }
  328. var validating = {}
  329. , total = 0;
  330. paths.forEach(validatePath);
  331. return this;
  332. function validatePath (path) {
  333. if (validating[path]) return;
  334. validating[path] = true;
  335. total++;
  336. process.nextTick(function(){
  337. var p = self.schema.path(path);
  338. if (!p) return --total || complete();
  339. var val = self.getValue(path);
  340. p.doValidate(val, function (err) {
  341. if (err) {
  342. self.invalidate(
  343. path
  344. , err
  345. , undefined
  346. , true // embedded docs
  347. );
  348. }
  349. --total || complete();
  350. }, self);
  351. });
  352. }
  353. function complete () {
  354. var err = self.$__.validationError;
  355. self.$__.validationError = undefined;
  356. self.emit('validate', self);
  357. cb(err);
  358. }
  359. };
  360. ```
  361. ---
  362. ### [Document#errors](#document_Document-errors)
  363. Hash containing current validation errors.
  364. show code
  365. ```
  366. Document.prototype.errors;
  367. ```
  368. ---
  369. ### [Document#id](#document_Document-id)
  370. The string version of this documents \_id.
  371. #### Note:
  372. This getter exists on all documents by default. The getter can be disabled by setting the `id` [option](https://mongoosejs.com/docs/guide.html#id) of its `Schema` to false at construction time.
  373. ```
  374. new Schema({ name: String }, { id: false });
  375. ```
  376. show code
  377. ```
  378. Document.prototype.id;
  379. ```
  380. #### See:
  381. - [Schema options](https://mongoosejs.com/docs/guide.html#options "Schema options")
  382. ---
  383. ### [Document#isNew](#document_Document-isNew)
  384. Boolean flag specifying if the document is new.
  385. show code
  386. ```
  387. Document.prototype.isNew;
  388. ```
  389. ---
  390. ### [Document#schema](#document_Document-schema)
  391. The documents schema.
  392. show code
  393. ```
  394. Document.prototype.schema;
  395. ```
  396. ---
  • types/array.js

    MongooseArray#_cast(value)

    Casts a member based on this arrays schema.

    Parameters:

    • value <T>

    Returns:

    • <value> the casted value

    show code

    1. MongooseArray.prototype._cast = function (value) {
    2. var owner = this._owner;
    3. var populated = false;
    4. var Model;
    5. if (this._parent) {
    6. // if a populated array, we must cast to the same model
    7. // instance as specified in the original query.
    8. if (!owner) {
    9. owner = this._owner = this._parent.ownerDocument
    10. ? this._parent.ownerDocument()
    11. : this._parent;
    12. }
    13. populated = owner.populated(this._path, true);
    14. }
    15. if (populated && null != value) {
    16. // cast to the populated Models schema
    17. var Model = populated.options.model;
    18. // only objects are permitted so we can safely assume that
    19. // non-objects are to be interpreted as _id
    20. if (Buffer.isBuffer(value) ||
    21. value instanceof ObjectId || !utils.isObject(value)) {
    22. value = { _id: value };
    23. }
    24. // gh-2399
    25. // we should cast model only when it's not a discriminator
    26. var isDisc = value.schema && value.schema.discriminatorMapping &&
    27. value.schema.discriminatorMapping.key !== undefined;
    28. if (!isDisc) {
    29. value = new Model(value);
    30. }
    31. return this._schema.caster.cast(value, this._parent, true)
    32. }
    33. return this._schema.caster.cast(value, this._parent, false)
    34. }

    MongooseArray#_markModified(embeddedDoc, embeddedPath)

    Marks this array as modified.

    Parameters:

    • embeddedDoc <EmbeddedDocument> the embedded doc that invoked this method on the Array
    • embeddedPath <String> the path which changed in the embeddedDoc

    If it bubbles up from an embedded document change, then it takes the following arguments (otherwise, takes 0 arguments)

    show code

    1. MongooseArray.prototype._markModified = function (elem, embeddedPath) {
    2. var parent = this._parent
    3. , dirtyPath;
    4. if (parent) {
    5. dirtyPath = this._path;
    6. if (arguments.length) {
    7. if (null != embeddedPath) {
    8. // an embedded doc bubbled up the change
    9. dirtyPath = dirtyPath + '.' + this.indexOf(elem) + '.' + embeddedPath;
    10. } else {
    11. // directly set an index
    12. dirtyPath = dirtyPath + '.' + elem;
    13. }
    14. }
    15. parent.markModified(dirtyPath);
    16. }
    17. return this;
    18. };

    MongooseArray#_registerAtomic(op, val)

    Register an atomic operation with the parent.

    Parameters:

    • op <Array> operation
    • val <T>

    show code

    1. MongooseArray.prototype._registerAtomic = function (op, val) {
    2. if ('$set' == op) {
    3. // $set takes precedence over all other ops.
    4. // mark entire array modified.
    5. this._atomics = { $set: val };
    6. return this;
    7. }
    8. var atomics = this._atomics;
    9. // reset pop/shift after save
    10. if ('$pop' == op && !('$pop' in atomics)) {
    11. var self = this;
    12. this._parent.once('save', function () {
    13. self._popped = self._shifted = null;
    14. });
    15. }
    16. // check for impossible $atomic combos (Mongo denies more than one
    17. // $atomic op on a single path
    18. if (this._atomics.$set ||
    19. Object.keys(atomics).length && !(op in atomics)) {
    20. // a different op was previously registered.
    21. // save the entire thing.
    22. this._atomics = { $set: this };
    23. return this;
    24. }
    25. if (op === '$pullAll' || op === '$pushAll' || op === '$addToSet') {
    26. atomics[op] || (atomics[op] = []);
    27. atomics[op] = atomics[op].concat(val);
    28. } else if (op === '$pullDocs') {
    29. var pullOp = atomics['$pull'] || (atomics['$pull'] = {})
    30. , selector = pullOp['_id'] || (pullOp['_id'] = {'$in' : [] });
    31. selector['$in'] = selector['$in'].concat(val);
    32. } else {
    33. atomics[op] = val;
    34. }
    35. return this;
    36. };

    MongooseArray#$__getAtomics()

    Depopulates stored atomic operation values as necessary for direct insertion to MongoDB.

    Returns:

    If no atomics exist, we return all array values after conversion.


    MongooseArray#$pop()

    Pops the array atomically at most one time per document save().

    See:

    NOTE:

    Calling this mulitple times on an array before saving sends the same command as calling it once.
    This update is implemented using the MongoDB $pop method which enforces this restriction.

    1. doc.array = [1,2,3];
    2. var popped = doc.array.$pop();
    3. console.log(popped); // 3
    4. console.log(doc.array); // [1,2]
    5. // no affect
    6. popped = doc.array.$pop();
    7. console.log(doc.array); // [1,2]
    8. doc.save(function (err) {
    9. if (err) return handleError(err);
    10. // we saved, now $pop works again
    11. popped = doc.array.$pop();
    12. console.log(popped); // 2
    13. console.log(doc.array); // [1]
    14. })

    MongooseArray#$shift()

    Atomically shifts the array at most one time per document save().

    See:

    NOTE:

    Calling this mulitple times on an array before saving sends the same command as calling it once.
    This update is implemented using the MongoDB $pop method which enforces this restriction.

    1. doc.array = [1,2,3];
    2. var shifted = doc.array.$shift();
    3. console.log(shifted); // 1
    4. console.log(doc.array); // [2,3]
    5. // no affect
    6. shifted = doc.array.$shift();
    7. console.log(doc.array); // [2,3]
    8. doc.save(function (err) {
    9. if (err) return handleError(err);
    10. // we saved, now $shift works again
    11. shifted = doc.array.$shift();
    12. console.log(shifted ); // 2
    13. console.log(doc.array); // [3]
    14. })

    MongooseArray#addToSet([args...])

    Adds values to the array if not already present.

    Parameters:

    • [args...] <T>

    Returns:

    • <Array> the values that were added

    Example:

    1. console.log(doc.array) // [2,3,4]
    2. var added = doc.array.addToSet(4,5);
    3. console.log(doc.array) // [2,3,4,5]
    4. console.log(added) // [5]

    show code

    1. MongooseArray.prototype.addToSet = function addToSet () {
    2. var values = [].map.call(arguments, this._cast, this)
    3. , added = []
    4. , type = values[0] instanceof EmbeddedDocument ? 'doc' :
    5. values[0] instanceof Date ? 'date' :
    6. '';
    7. values.forEach(function (v) {
    8. var found;
    9. switch (type) {
    10. case 'doc':
    11. found = this.some(function(doc){ return doc.equals(v) });
    12. break;
    13. case 'date':
    14. var val = +v;
    15. found = this.some(function(d){ return +d === val });
    16. break;
    17. default:
    18. found = ~this.indexOf(v);
    19. }
    20. if (!found) {
    21. [].push.call(this, v);
    22. this._registerAtomic('$addToSet', v);
    23. this._markModified();
    24. [].push.call(added, v);
    25. }
    26. }, this);
    27. return added;
    28. };

    MongooseArray#hasAtomics()

    Returns the number of pending atomic operations to send to the db for this array.

    Returns:

    show code

    1. MongooseArray.prototype.hasAtomics = function hasAtomics () {
    2. if (!(this._atomics && 'Object' === this._atomics.constructor.name)) {
    3. return 0;
    4. }
    5. return Object.keys(this._atomics).length;
    6. }

    MongooseArray#indexOf(obj)

    Return the index of obj or -1 if not found.

    Parameters:

    • obj <Object> the item to look for

    Returns:

    show code

    1. MongooseArray.prototype.indexOf = function indexOf (obj) {
    2. if (obj instanceof ObjectId) obj = obj.toString();
    3. for (var i = 0, len = this.length; i < len; ++i) {
    4. if (obj == this[i])
    5. return i;
    6. }
    7. return -1;
    8. };

    MongooseArray#inspect()

    Helper for console.log

    show code

    1. MongooseArray.prototype.inspect = function () {
    2. return JSON.stringify(this);
    3. };

    MongooseArray(values, path, doc)

    Mongoose Array constructor.

    Parameters:

    Inherits:

    See:

    NOTE:

    Values always have to be passed to the constructor to initialize, otherwise MongooseArray#push will mark the array as modified.

    show code

    1. function MongooseArray (values, path, doc) {
    2. var arr = [].concat(values);;
    3. arr.__proto__ = MongooseArray.prototype;
    4. Object.defineProperty(arr, '_atomics', { enumerable: false, configurable: true, writable: true });
    5. Object.defineProperty(arr, 'validators', { enumerable: false, configurable: true, writable: true });
    6. Object.defineProperty(arr, '_path', {enumerable: false, configurable: true, writable: true });
    7. Object.defineProperty(arr, '_parent', { enumerable: false, configurable: true, writable: true });
    8. Object.defineProperty(arr, '_schema', { enumerable: false, configurable: true, writable: true });
    9. arr._atomics = {};
    10. arr.validators = [];
    11. arr._path = path;
    12. if (doc) {
    13. arr._parent = doc;
    14. arr._schema = doc.schema.path(path);
    15. }
    16. return arr;
    17. };

    MongooseArray#nonAtomicPush([args...])

    Pushes items to the array non-atomically.

    Parameters:

    • [args...] <T>

    NOTE:

    marks the entire array as modified, which if saved, will store it as a $set operation, potentially overwritting any changes that happen between when you retrieved the object and when you save it.

    show code

    1. MongooseArray.prototype.nonAtomicPush = function () {
    2. var values = [].map.call(arguments, this._cast, this)
    3. , ret = [].push.apply(this, values);
    4. this._registerAtomic('$set', this);
    5. this._markModified();
    6. return ret;
    7. };

    MongooseArray#pop()

    Wraps Array#pop with proper change tracking.

    See:

    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.

    show code

    1. MongooseArray.prototype.pop = function () {
    2. var ret = [].pop.call(this);
    3. this._registerAtomic('$set', this);
    4. this._markModified();
    5. return ret;
    6. };

    MongooseArray#pull([args...])

    Pulls items from the array atomically.

    Parameters:

    • [args...] <T>

    See:

    Examples:

    1. doc.array.pull(ObjectId)
    2. doc.array.pull({ _id: 'someId' })
    3. doc.array.pull(36)
    4. doc.array.pull('tag 1', 'tag 2')

    To remove a document from a subdocument array we may pass an object with a matching _id.

    1. doc.subdocs.push({ _id: 4815162342 })
    2. doc.subdocs.pull({ _id: 4815162342 }) // removed

    Or we may passing the _id directly and let mongoose take care of it.

    1. doc.subdocs.push({ _id: 4815162342 })
    2. doc.subdocs.pull(4815162342); // works

    show code

    1. MongooseArray.prototype.pull = function () {
    2. var values = [].map.call(arguments, this._cast, this)
    3. , cur = this._parent.get(this._path)
    4. , i = cur.length
    5. , mem;
    6. while (i--) {
    7. mem = cur[i];
    8. if (mem instanceof EmbeddedDocument) {
    9. if (values.some(function (v) { return v.equals(mem); } )) {
    10. [].splice.call(cur, i, 1);
    11. }
    12. } else if (~cur.indexOf.call(values, mem)) {
    13. [].splice.call(cur, i, 1);
    14. }
    15. }
    16. if (values[0] instanceof EmbeddedDocument) {
    17. this._registerAtomic('$pullDocs', values.map( function (v) { return v._id; } ));
    18. } else {
    19. this._registerAtomic('$pullAll', values);
    20. }
    21. this._markModified();
    22. return this;
    23. };

    MongooseArray#push([args...])

    Wraps Array#push with proper change tracking.

    Parameters:

    show code

    1. MongooseArray.prototype.push = function () {
    2. var values = [].map.call(arguments, this._cast, this)
    3. , ret = [].push.apply(this, values);
    4. // $pushAll might be fibbed (could be $push). But it makes it easier to
    5. // handle what could have been $push, $pushAll combos
    6. this._registerAtomic('$pushAll', values);
    7. this._markModified();
    8. return ret;
    9. };

    MongooseArray#remove()

    Alias of pull

    See:


    MongooseArray#set()

    Sets the casted val at index i and marks the array modified.

    Returns:

    Example:

    1. // given documents based on the following
    2. var Doc = mongoose.model('Doc', new Schema({ array: [Number] }));
    3. var doc = new Doc({ array: [2,3,4] })
    4. console.log(doc.array) // [2,3,4]
    5. doc.array.set(1,"5");
    6. console.log(doc.array); // [2,5,4] // properly cast to number
    7. doc.save() // the change is saved
    8. // VS not using array#set
    9. doc.array[1] = "5";
    10. console.log(doc.array); // [2,"5",4] // no casting
    11. doc.save() // change is not saved

    show code

    1. MongooseArray.prototype.set = function set (i, val) {
    2. this[i] = this._cast(val);
    3. this._markModified(i);
    4. return this;
    5. }

    MongooseArray#shift()

    Wraps Array#shift with proper change tracking.

    Example:

    1. doc.array = [2,3];
    2. var res = doc.array.shift();
    3. console.log(res) // 2
    4. console.log(doc.array) // [3]

    Note:

    marks the entire array as modified, which if saved, will store it as a $set operation, potentially overwritting any changes that happen between when you retrieved the object and when you save it.

    show code

    1. MongooseArray.prototype.shift = function () {
    2. var ret = [].shift.call(this);
    3. this._registerAtomic('$set', this);
    4. this._markModified();
    5. return ret;
    6. };

    MongooseArray#sort()

    Wraps Array#sort with proper change tracking.

    NOTE:

    marks the entire array as modified, which if saved, will store it as a $set operation, potentially overwritting any changes that happen between when you retrieved the object and when you save it.

    show code

    1. MongooseArray.prototype.sort = function () {
    2. var ret = [].sort.apply(this, arguments);
    3. this._registerAtomic('$set', this);
    4. this._markModified();
    5. return ret;
    6. }

    MongooseArray#splice()

    Wraps Array#splice with proper change tracking and casting.

    Note:

    marks the entire array as modified, which if saved, will store it as a $set operation, potentially overwritting any changes that happen between when you retrieved the object and when you save it.

    show code

    1. MongooseArray.prototype.splice = function splice () {
    2. var ret, vals, i;
    3. if (arguments.length) {
    4. vals = [];
    5. for (i = 0; i < arguments.length; ++i) {
    6. vals[i] = i < 2
    7. ? arguments[i]
    8. : this._cast(arguments[i]);
    9. }
    10. ret = [].splice.apply(this, vals);
    11. this._registerAtomic('$set', this);
    12. this._markModified();
    13. }
    14. return ret;
    15. }

    MongooseArray#toObject(options)

    Returns a native js Array.

    Parameters:

    Returns:

    show code

    1. MongooseArray.prototype.toObject = function (options) {
    2. if (options && options.depopulate) {
    3. return this.map(function (doc) {
    4. return doc instanceof Document
    5. ? doc.toObject(options)
    6. : doc
    7. });
    8. }
    9. return this.slice();
    10. }

    MongooseArray#unshift()

    Wraps Array#unshift with proper change tracking.

    Note:

    marks the entire array as modified, which if saved, will store it as a $set operation, potentially overwritting any changes that happen between when you retrieved the object and when you save it.

    show code

    1. MongooseArray.prototype.unshift = function () {
    2. var values = [].map.call(arguments, this._cast, this);
    3. [].unshift.apply(this, values);
    4. this._registerAtomic('$set', this);
    5. this._markModified();
    6. return this.length;
    7. };

    MongooseArray#_atomics

    Stores a queue of atomic operations to perform

    show code

    1. MongooseArray.prototype._atomics;

    MongooseArray#_parent

    Parent owner document

    show code

    1. MongooseArray.prototype._parent;

  • types/documentarray.js

    MongooseDocumentArray#_cast()

    Overrides MongooseArray#cast

    show code

    1. MongooseDocumentArray.prototype._cast = function (value) {
    2. if (value instanceof this._schema.casterConstructor) {
    3. if (!(value.__parent && value.__parentArray)) {
    4. // value may have been created using array.create()
    5. value.__parent = this._parent;
    6. value.__parentArray = this;
    7. }
    8. return value;
    9. }
    10. // handle cast('string') or cast(ObjectId) etc.
    11. // only objects are permitted so we can safely assume that
    12. // non-objects are to be interpreted as _id
    13. if (Buffer.isBuffer(value) ||
    14. value instanceof ObjectId || !utils.isObject(value)) {
    15. value = { _id: value };
    16. }
    17. return new this._schema.casterConstructor(value, this);
    18. };

    MongooseDocumentArray#create(obj)

    Creates a subdocument casted to this schema.

    Parameters:

    • obj <Object> the value to cast to this arrays SubDocument schema

    This is the same subdocument constructor used for casting.

    show code

    1. MongooseDocumentArray.prototype.create = function (obj) {
    2. return new this._schema.casterConstructor(obj);
    3. }

    MongooseDocumentArray#id(id)

    Searches array items for the first document with a matching _id.

    Parameters:

    Returns:

    Example:

    1. var embeddedDoc = m.array.id(some_id);

    show code

    1. MongooseDocumentArray.prototype.id = function (id) {
    2. var casted
    3. , sid
    4. , _id
    5. try {
    6. var casted_ = ObjectIdSchema.prototype.cast.call({}, id);
    7. if (casted_) casted = String(casted_);
    8. } catch (e) {
    9. casted = null;
    10. }
    11. for (var i = 0, l = this.length; i < l; i++) {
    12. _id = this[i].get('_id');
    13. if (_id instanceof Document) {
    14. sid || (sid = String(id));
    15. if (sid == _id._id) return this[i];
    16. } else if (!(_id instanceof ObjectId)) {
    17. sid || (sid = String(id));
    18. if (sid == _id) return this[i];
    19. } else if (casted == _id) {
    20. return this[i];
    21. }
    22. }
    23. return null;
    24. };

    MongooseDocumentArray#inspect()

    Helper for console.log

    show code

    1. MongooseDocumentArray.prototype.inspect = function () {
    2. return '[' + this.map(function (doc) {
    3. if (doc) {
    4. return doc.inspect
    5. ? doc.inspect()
    6. : util.inspect(doc)
    7. }
    8. return 'null'
    9. }).join('
    10. ') + ']';
    11. };

    MongooseDocumentArray(values, path, doc)

    DocumentArray constructor

    Parameters:

    Returns:

    Inherits:

    See:

    show code

    1. function MongooseDocumentArray (values, path, doc) {
    2. var arr = [];
    3. // Values always have to be passed to the constructor to initialize, since
    4. // otherwise MongooseArray#push will mark the array as modified to the parent.
    5. arr = arr.concat(values);
    6. arr.__proto__ = MongooseDocumentArray.prototype;
    7. arr._atomics = {};
    8. arr.validators = [];
    9. arr._path = path;
    10. if (doc) {
    11. arr._parent = doc;
    12. arr._schema = doc.schema.path(path);
    13. arr._handlers = {
    14. isNew: arr.notify('isNew'),
    15. save: arr.notify('save')
    16. }
    17. doc.on('save', arr._handlers.save);
    18. doc.on('isNew', arr._handlers.isNew);
    19. }
    20. return arr;
    21. };

    MongooseDocumentArray#notify(event)

    Creates a fn that notifies all child docs of event.

    Parameters:

    Returns:

    show code

    1. MongooseDocumentArray.prototype.notify = function notify (event) {
    2. var self = this;
    3. return function notify (val) {
    4. var i = self.length;
    5. while (i--) {
    6. if (!self[i]) continue;
    7. switch(event) {
    8. // only swap for save event for now, we may change this to all event types later
    9. case 'save':
    10. val = self[i];
    11. break;
    12. default:
    13. // NO-OP
    14. break;
    15. }
    16. self[i].emit(event, val);
    17. }
    18. }
    19. }

    MongooseDocumentArray#toObject([options])

    Returns a native js Array of plain js objects

    Parameters:

    • [options] <Object> optional options to pass to each documents `toObject` method call during conversion

    Returns:

    NOTE:

    Each sub-document is converted to a plain object by calling its #toObject method.

    show code

    1. MongooseDocumentArray.prototype.toObject = function (options) {
    2. return this.map(function (doc) {
    3. return doc && doc.toObject(options) || null;
    4. });
    5. };

  • types/buffer.js

    MongooseBuffer#_markModified()

    Marks this buffer as modified.

    show code

    1. MongooseBuffer.prototype._markModified = function () {
    2. var parent = this._parent;
    3. if (parent) {
    4. parent.markModified(this._path);
    5. }
    6. return this;
    7. };

    MongooseBuffer#copy(target)

    Copies the buffer.

    Parameters:

    Returns:

    Note:

    Buffer#copy does not mark target as modified so you must copy from a MongooseBuffer for it to work as expected. This is a work around since copy modifies the target, not this.

    show code

    1. MongooseBuffer.prototype.copy = function (target) {
    2. var ret = Buffer.prototype.copy.apply(this, arguments);
    3. if (target instanceof MongooseBuffer) {
    4. target._markModified();
    5. }
    6. return ret;
    7. };

    MongooseBuffer#equals(other)

    Determines if this buffer is equals to other buffer

    Parameters:

    Returns:

    show code

    1. MongooseBuffer.prototype.equals = function (other) {
    2. if (!Buffer.isBuffer(other)) {
    3. return false;
    4. }
    5. if (this.length !== other.length) {
    6. return false;
    7. }
    8. for (var i = 0; i < this.length; ++i) {
    9. if (this[i] !== other[i]) return false;
    10. }
    11. return true;
    12. }

    MongooseBuffer(value, encode, offset)

    Mongoose Buffer constructor.

    Parameters:

    Inherits:

    See:

    Values always have to be passed to the constructor to initialize.

    show code

    1. function MongooseBuffer (value, encode, offset) {
    2. var length = arguments.length;
    3. var val;
    4. if (0 === length || null === arguments[0] || undefined === arguments[0]) {
    5. val = 0;
    6. } else {
    7. val = value;
    8. }
    9. var encoding;
    10. var path;
    11. var doc;
    12. if (Array.isArray(encode)) {
    13. // internal casting
    14. path = encode[0];
    15. doc = encode[1];
    16. } else {
    17. encoding = encode;
    18. }
    19. var buf = new Buffer(val, encoding, offset);
    20. buf.__proto__ = MongooseBuffer.prototype;
    21. // make sure these internal props don't show up in Object.keys()
    22. Object.defineProperties(buf, {
    23. validators: { value: [] }
    24. , _path: { value: path }
    25. , _parent: { value: doc }
    26. });
    27. if (doc && "string" === typeof path) {
    28. Object.defineProperty(buf, '_schema', {
    29. value: doc.schema.path(path)
    30. });
    31. }
    32. buf._subtype = 0;
    33. return buf;
    34. };

    MongooseBuffer#subtype(subtype)

    Sets the subtype option and marks the buffer modified.

    Parameters:

    See:

    SubTypes:

    var bson = require(‘bson’)
    bson.BSON_BINARY_SUBTYPE_DEFAULT
    bson.BSON_BINARY_SUBTYPE_FUNCTION
    bson.BSON_BINARY_SUBTYPE_BYTE_ARRAY
    bson.BSON_BINARY_SUBTYPE_UUID
    bson.BSON_BINARY_SUBTYPE_MD5
    bson.BSON_BINARY_SUBTYPE_USER_DEFINED

    doc.buffer.subtype(bson.BSON_BINARY_SUBTYPE_UUID);

    show code

    MongooseBuffer.prototype.subtype = function (subtype) {
      if ('number' != typeof subtype) {
        throw new TypeError('Invalid subtype. Expected a number');
      }
    
      if (this._subtype != subtype) {
        this._markModified();
      }
    
      this._subtype = subtype;
    }
    

    MongooseBuffer#toObject([subtype])

    Converts this buffer to its Binary type representation.

    Parameters:

    • [subtype] <Hex>

    Returns:

    See:

    SubTypes:

    var bson = require(‘bson’)
    bson.BSON_BINARY_SUBTYPE_DEFAULT
    bson.BSON_BINARY_SUBTYPE_FUNCTION
    bson.BSON_BINARY_SUBTYPE_BYTE_ARRAY
    bson.BSON_BINARY_SUBTYPE_UUID
    bson.BSON_BINARY_SUBTYPE_MD5
    bson.BSON_BINARY_SUBTYPE_USER_DEFINED

    doc.buffer.toObject(bson.BSON_BINARY_SUBTYPE_USER_DEFINED);

    show code

    MongooseBuffer.prototype.toObject = function (options) {
      var subtype = 'number' == typeof options
        ? options
        : (this._subtype || 0);
      return new Binary(this, subtype);
    };
    

    MongooseBuffer#write()

    Writes the buffer.

    show code

    MongooseBuffer.prototype.write = function () {
      var written = Buffer.prototype.write.apply(this, arguments);
    
      if (written > 0) {
        this._markModified();
      }
    
      return written;
    };
    

    MongooseBuffer#_parent

    Parent owner document

    show code

    MongooseBuffer.prototype._parent;
    

    MongooseBuffer#_subtype

    Default subtype for the Binary representing this Buffer

    show code

    MongooseBuffer.prototype._subtype;
    

  • types/objectid.js

    ObjectId()

    ObjectId type constructor

    Example

    var id = new mongoose.Types.ObjectId;
    

  • types/embedded.js

    EmbeddedDocument#$__fullPath([path])

    Returns the full path to this document. If optional path is passed, it is appended to the full path.

    Parameters:

    Returns:


    EmbeddedDocument(obj, parentArr, skipId)

    EmbeddedDocument constructor.

    Parameters:

    Inherits:

    show code

    function EmbeddedDocument (obj, parentArr, skipId, fields) {
      if (parentArr) {
        this.__parentArray = parentArr;
        this.__parent = parentArr._parent;
      } else {
        this.__parentArray = undefined;
        this.__parent = undefined;
      }
    
      Document.call(this, obj, fields, skipId);
    
      var self = this;
      this.on('isNew', function (val) {
        self.isNew = val;
      });
    };
    

    EmbeddedDocument#inspect()

    Helper for console.log

    show code

    EmbeddedDocument.prototype.inspect = function () {
      return inspect(this.toObject());
    };
    

    EmbeddedDocument#invalidate(path, err)

    Marks a path as invalid, causing validation to fail.

    Parameters:

    • path <String> the field to invalidate
    • err <String, Error> error which states the reason `path` was invalid

    Returns:

    show code

    EmbeddedDocument.prototype.invalidate = function (path, err, val, first) {
      if (!this.__parent) {
        var msg = 'Unable to invalidate a subdocument that has not been added to an array.'
        throw new Error(msg);
      }
    
      var index = this.__parentArray.indexOf(this);
      var parentPath = this.__parentArray._path;
      var fullPath = [parentPath, index, path].join('.');
    
      // sniffing arguments:
      // need to check if user passed a value to keep
      // our error message clean.
      if (2 < arguments.length) {
        this.__parent.invalidate(fullPath, err, val);
      } else {
        this.__parent.invalidate(fullPath, err);
      }
    
      if (first)
        this.$__.validationError = this.ownerDocument().$__.validationError;
      return true;
    }
    

    EmbeddedDocument#markModified(path)

    Marks the embedded doc modified.

    Parameters:

    • path <String> the path which changed

    Example:

    var doc = blogpost.comments.id(hexstring);
    doc.mixed.type = 'changed';
    doc.markModified('mixed.type');
    

    show code

    EmbeddedDocument.prototype.markModified = function (path) {
      if (!this.__parentArray) return;
    
      this.$__.activePaths.modify(path);
      if (this.isNew) {
        // Mark the WHOLE parent array as modified
        // if this is a new document (i.e., we are initializing
        // a document),
        this.__parentArray._markModified();
      } else {
        this.__parentArray._markModified(this, path);
      }
    };
    

    EmbeddedDocument#ownerDocument()

    Returns the top level document of this sub-document.

    Returns:

    show code

    EmbeddedDocument.prototype.ownerDocument = function () {
      if (this.$__.ownerDocument) {
        return this.$__.ownerDocument;
      }
    
      var parent = this.__parent;
      if (!parent) return this;
    
      while (parent.__parent) {
        parent = parent.__parent;
      }
    
      return this.$__.ownerDocument = parent;
    }
    

    EmbeddedDocument#parent()

    Returns this sub-documents parent document.

    show code

    EmbeddedDocument.prototype.parent = function () {
      return this.__parent;
    }
    

    EmbeddedDocument#parentArray()

    Returns this sub-documents parent array.

    show code

    EmbeddedDocument.prototype.parentArray = function () {
      return this.__parentArray;
    }
    

    EmbeddedDocument#remove([fn])

    Removes the subdocument from its parent array.

    Parameters:

    show code

    EmbeddedDocument.prototype.remove = function (fn) {
      if (!this.__parentArray) return this;
    
      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;
        registerRemoveListener(this);
      }
    
      if (fn)
        fn(null);
    
      return this;
    };
    

    EmbeddedDocument#save([fn])

    Used as a stub for hooks.js

    Parameters:

    Returns:

    NOTE:

    This is a no-op. Does not actually save the doc to the db.

    show code

    EmbeddedDocument.prototype.save = function(fn) {
      if (fn)
        fn(null);
      return this;
    };
    

    EmbeddedDocument#update()

    Override #update method of parent documents.

    show code

    EmbeddedDocument.prototype.update = function () {
      throw new Error('The #update method is not available on EmbeddedDocuments');
    }
    

  • query.js

    Query#_applyPaths()

    Applies schematype selected options to this query.

    show code

    Query.prototype._applyPaths = function applyPaths () {
      // determine if query is selecting or excluding fields
    
      var fields = this._fields
        , exclude
        , keys
        , ki
    
      if (fields) {
        keys = Object.keys(fields);
        ki = keys.length;
    
        while (ki--) {
          if ('+' == keys[ki][0]) continue;
          exclude = 0 === fields[keys[ki]];
          break;
        }
      }
    
      // if selecting, apply default schematype select:true fields
      // if excluding, apply schematype select:false fields
    
      var selected = []
        , excluded = []
        , seen = [];
    
      analyzeSchema(this.model.schema);
    
      switch (exclude) {
        case true:
          excluded.length && this.select('-' + excluded.join(' -'));
          break;
        case false:
          selected.length && this.select(selected.join(' '));
          break;
        case undefined:
          // user didn't specify fields, implies returning all fields.
          // only need to apply excluded fields
          excluded.length && this.select('-' + excluded.join(' -'));
          break;
      }
    
      return seen = excluded = selected = keys = fields = null;
    
      function analyzeSchema (schema, prefix) {
        prefix || (prefix = '');
    
        // avoid recursion
        if (~seen.indexOf(schema)) return;
        seen.push(schema);
    
        schema.eachPath(function (path, type) {
          if (prefix) path = prefix + '.' + path;
    
          analyzePath(path, type);
    
          // array of subdocs?
          if (type.schema) {
            analyzeSchema(type.schema, path);
          }
    
        });
      }
    
      function analyzePath (path, type) {
        if ('boolean' != typeof type.selected) return;
    
        var plusPath = '+' + path;
        if (fields && plusPath in fields) {
          // forced inclusion
          delete fields[plusPath];
    
          // if there are other fields being included, add this one
          // if no other included fields, leave this out (implied inclusion)
          if (false === exclude && keys.length > 1 && !~keys.indexOf(path)) {
            fields[path] = 1;
          }
    
          return
        };
    
        // check for parent exclusions
        var root = path.split('.')[0];
        if (~excluded.indexOf(root)) return;
    
        ;(type.selected ? selected : excluded).push(path);
      }
    }
    

    Query#_castFields(fields)

    Casts selected field arguments for field selection with mongo 2.2

    Parameters:

    See:

    query.select({ ids: { $elemMatch: { $in: [hexString] }})
    

    show code

    Query.prototype._castFields = function _castFields (fields) {
      var selected
        , elemMatchKeys
        , keys
        , key
        , out
        , i
    
      if (fields) {
        keys = Object.keys(fields);
        elemMatchKeys = [];
        i = keys.length;
    
        // collect $elemMatch args
        while (i--) {
          key = keys[i];
          if (fields[key].$elemMatch) {
            selected || (selected = {});
            selected[key] = fields[key];
            elemMatchKeys.push(key);
          }
        }
      }
    
      if (selected) {
        // they passed $elemMatch, cast em
        try {
          out = this.cast(this.model, selected);
        } catch (err) {
          return err;
        }
    
        // apply the casted field args
        i = elemMatchKeys.length;
        while (i--) {
          key = elemMatchKeys[i];
          fields[key] = out[key];
        }
      }
    
      return fields;
    }
    

    Query#_castFields(fields)

    Casts selected field arguments for field selection with mongo 2.2

    Parameters:

    See:

    query.select({ ids: { $elemMatch: { $in: [hexString] }})
    

    show code

    Query.prototype._castFields = function _castFields (fields) {
      var selected
        , elemMatchKeys
        , keys
        , key
        , out
        , i
    
      if (fields) {
        keys = Object.keys(fields);
        elemMatchKeys = [];
        i = keys.length;
    
        // collect $elemMatch args
        while (i--) {
          key = keys[i];
          if (fields[key].$elemMatch) {
            selected || (selected = {});
            selected[key] = fields[key];
            elemMatchKeys.push(key);
          }
        }
      }
    
      if (selected) {
        // they passed $elemMatch, cast em
        try {
          out = this.cast(this.model, selected);
        } catch (err) {
          return err;
        }
    
        // apply the casted field args
        i = elemMatchKeys.length;
        while (i--) {
          key = elemMatchKeys[i];
          fields[key] = out[key];
        }
      }
    
      return fields;
    }
    

    Query#_castUpdate(obj)

    Casts obj for an update command.

    Parameters:

    Returns:

    • <Object> obj after casting its values

    show code

    Query.prototype._castUpdate = function _castUpdate (obj, overwrite) {
      if (!obj) return undefined;
    
      var ops = Object.keys(obj)
        , i = ops.length
        , ret = {}
        , hasKeys
        , val;
    
      while (i--) {
        var op = ops[i];
        // if overwrite is set, don't do any of the special $set stuff
        if ('$' !== op[0] && !overwrite) {
          // fix up $set sugar
          if (!ret.$set) {
            if (obj.$set) {
              ret.$set = obj.$set;
            } else {
              ret.$set = {};
            }
          }
          ret.$set[op] = obj[op];
          ops.splice(i, 1);
          if (!~ops.indexOf('$set')) ops.push('$set');
        } else if ('$set' === op) {
          if (!ret.$set) {
            ret[op] = obj[op];
          }
        } else {
          ret[op] = obj[op];
        }
      }
    
      // cast each value
      i = ops.length;
    
      // if we get passed {} for the update, we still need to respect that when it
      // is an overwrite scenario
      if (overwrite) {
        hasKeys = true;
      }
    
      while (i--) {
        op = ops[i];
        val = ret[op];
        if (val && 'Object' === val.constructor.name && !overwrite) {
          hasKeys |= this._walkUpdatePath(val, op);
        } else if (overwrite && 'Object' === ret.constructor.name) {
          // if we are just using overwrite, cast the query and then we will
          // *always* return the value, even if it is an empty object. We need to
          // set hasKeys above because we need to account for the case where the
          // user passes {} and wants to clobber the whole document
          // Also, _walkUpdatePath expects an operation, so give it $set since that
          // is basically what we're doing
          this._walkUpdatePath(ret.$set || ret, '$set');
        } else {
          var msg = 'Invalid atomic update value for ' + op + '. '
                  + 'Expected an object, received ' + typeof val;
          throw new Error(msg);
        }
      }
    
      return hasKeys && ret;
    }
    

    Query#_castUpdateVal(schema, val, op, [$conditional])

    Casts val according to schema and atomic op.

    Parameters:

    show code

    Query.prototype._castUpdateVal = function _castUpdateVal (schema, val, op, $conditional) {
      if (!schema) {
        // non-existing schema path
        return op in numberOps
          ? Number(val)
          : val
      }
    
      var cond = schema.caster && op in castOps &&
        (utils.isObject(val) || Array.isArray(val));
      if (cond) {
        // Cast values for ops that add data to MongoDB.
        // Ensures embedded documents get ObjectIds etc.
        var tmp = schema.cast(val);
    
        if (Array.isArray(val)) {
          val = tmp;
        } else {
          val = tmp[0];
        }
      }
    
      if (op in numberOps) {
        return Number(val);
      }
      if (op === '$currentDate') {
        if (typeof val === 'object') {
          return { $type: val.$type };
        }
        return Boolean(val);
      }
      if (/^\$/.test($conditional)) {
        return schema.castForQuery($conditional, val);
      }
      return schema.castForQuery(val)
    }
    

    function Object() { [native code] }#_ensurePath(method)%20%7B%20%5Bnative%20code%5D%20%7D-_ensurePath)

    Makes sure _path is set.

    Parameters:


    function Object() { [native code] }#_fieldsForExec()%20%7B%20%5Bnative%20code%5D%20%7D-_fieldsForExec)

    Returns fields selection for this query.

    Returns:


    Query#_findAndModify(type, callback)

    Override mquery.prototype._findAndModify to provide casting etc.

    Parameters:

    • type <String> - either “remove” or “update”
    • callback <Function>

    show code

    Query.prototype._findAndModify = function (type, callback) {
      if ('function' != typeof callback) {
        throw new Error("Expected callback in _findAndModify");
      }
    
      var model = this.model
        , promise = new Promise(callback)
        , self = this
        , castedQuery
        , castedDoc
        , fields
        , opts;
    
      castedQuery = castQuery(this);
      if (castedQuery instanceof Error) {
        process.nextTick(promise.error.bind(promise, castedQuery));
        return promise;
      }
    
      opts = this._optionsForExec(model);
    
      if ('remove' == type) {
        opts.remove = true;
      } else {
        if (!('new' in opts)) opts.new = true;
        if (!('upsert' in opts)) opts.upsert = false;
        if (opts['new'] || opts.upsert) {
          opts.remove = false;
        }
    
        castedDoc = castDoc(this, opts.overwrite);
        if (!castedDoc) {
          if (opts.upsert) {
            // still need to do the upsert to empty doc
            var doc = utils.clone(castedQuery);
            delete doc._id;
            castedDoc = { $set: doc };
          } else {
            return this.findOne(callback);
          }
        } else if (castedDoc instanceof Error) {
          process.nextTick(promise.error.bind(promise, castedDoc));
          return promise;
        } else {
          // In order to make MongoDB 2.6 happy (see
          // https://jira.mongodb.org/browse/SERVER-12266 and related issues)
          // if we have an actual update document but $set is empty, junk the $set.
          if (castedDoc.$set && Object.keys(castedDoc.$set).length === 0) {
            delete castedDoc.$set;
          }
        }
      }
    
      this._applyPaths();
    
      var self = this;
      var options = this._mongooseOptions;
    
      if (this._fields) {
        fields = utils.clone(this._fields);
        opts.fields = this._castFields(fields);
        if (opts.fields instanceof Error) {
          process.nextTick(promise.error.bind(promise, opts.fields));
          return promise;
        }
      }
    
      if (opts.sort) convertSortToArray(opts);
    
      this._collection.findAndModify(castedQuery, castedDoc, opts, utils.tick(cb));
      function cb (err, doc) {
        if (err) return promise.error(err);
    
        if (!doc || (utils.isObject(doc) && Object.keys(doc).length === 0)) {
          return promise.complete(null);
        }
    
        if (!options.populate) {
          return true === options.lean
            ? promise.complete(doc)
            : completeOne(self.model, doc, fields, self, null, promise);
        }
    
        var pop = helpers.preparePopulationOptionsMQ(self, options);
        self.model.populate(doc, pop, function (err, doc) {
          if (err) return promise.error(err);
    
          return true === options.lean
            ? promise.complete(doc)
            : completeOne(self.model, doc, fields, self, pop, promise);
        });
      }
    
      return promise;
    }
    

    Query#_getSchema(path)

    Finds the schema for path. This is different than
    calling schema.path as it also resolves paths with
    positional selectors (something.$.another.$.path).

    Parameters:

    show code

    Query.prototype._getSchema = function _getSchema (path) {
      return this.model._getSchema(path);
    }
    

    Query#_mergeUpdate(doc)

    Override mquery.prototype._mergeUpdate to handle mongoose objects in
    updates.

    Parameters:

    show code

    Query.prototype._mergeUpdate = function(doc) {
      if (!this._update) this._update = {};
      if (doc instanceof Query) {
        if (doc._update) {
          utils.mergeClone(this._update, doc._update);
        }
      } else {
        utils.mergeClone(this._update, doc);
      }
    };
    

    Query#_optionsForExec(model)

    Returns default options for this query.

    Parameters:

    show code

    Query.prototype._optionsForExec = function (model) {
      var options = Query.base._optionsForExec.call(this);
    
      delete options.populate;
      model = model || this.model;
    
      if (!model) {
        return options;
      } else {
        if (!('safe' in options) && model.schema.options.safe) {
          options.safe = model.schema.options.safe;
        }
    
        if (!('readPreference' in options) && model.schema.options.read) {
          options.readPreference = model.schema.options.read;
        }
    
        return options;
      }
    };
    

    ()

    Determines if query fields are inclusive

    Returns:

    show code

    Query.prototype._selectedInclusively = Query.prototype.selectedInclusively;
    

    function Object() { [native code] }#_updateForExec()%20%7B%20%5Bnative%20code%5D%20%7D-_updateForExec)

    Return an update document with corrected $set operations.


    Query#_walkUpdatePath(obj, op, pref)

    Walk each path of obj and cast its values
    according to its schema.

    Parameters:

    • obj <Object> - part of a query
    • op <String> - the atomic operator ($pull, $set, etc)
    • pref <String> - path prefix (internal only)

    Returns:

    • <Bool> true if this path has keys to update

    show code

    Query.prototype._walkUpdatePath = function _walkUpdatePath (obj, op, pref) {
      var prefix = pref ? pref + '.' : ''
        , keys = Object.keys(obj)
        , i = keys.length
        , hasKeys = false
        , schema
        , key
        , val;
    
      var strict = 'strict' in this._mongooseOptions
        ? this._mongooseOptions.strict
        : this.model.schema.options.strict;
    
      while (i--) {
        key = keys[i];
        val = obj[key];
    
        if (val && 'Object' === val.constructor.name) {
          // watch for embedded doc schemas
          schema = this._getSchema(prefix + key);
          if (schema && schema.caster && op in castOps) {
            // embedded doc schema
    
            if (strict && !schema) {
              // path is not in our strict schema
              if ('throw' == strict) {
                throw new Error('Field `' + key + '` is not in schema.');
              } else {
                // ignore paths not specified in schema
                delete obj[key];
              }
            } else {
              hasKeys = true;
    
              if ('$each' in val) {
                obj[key] = {
                  $each: this._castUpdateVal(schema, val.$each, op)
                }
    
                if (val.$slice) {
                  obj[key].$slice = val.$slice | 0;
                }
    
                if (val.$sort) {
                  obj[key].$sort = val.$sort;
                }
    
                if (!!val.$position || val.$position === 0) {
                  obj[key].$position = val.$position;
                }
              } else {
                obj[key] = this._castUpdateVal(schema, val, op);
              }
            }
          } else if (op === '$currentDate') {
            // $currentDate can take an object
            obj[key] = this._castUpdateVal(schema, val, op);
          } else {
            // gh-2314
            // we should be able to set a schema-less field
            // to an empty object literal
            hasKeys |= this._walkUpdatePath(val, op, prefix + key) ||
                       (utils.isObject(val) && Object.keys(val).length === 0);
          }
        } else {
          schema = ('$each' === key || '$or' === key || '$and' === key)
            ? this._getSchema(pref)
            : this._getSchema(prefix + key);
    
          var skip = strict &&
                     !schema &&
                     !/real|nested/.test(this.model.schema.pathType(prefix + key));
    
          if (skip) {
            if ('throw' == strict) {
              throw new Error('Field `' + prefix + key + '` is not in schema.');
            } else {
              delete obj[key];
            }
          } else {
            if (op === '$rename') {
              hasKeys = true;
              return;
            }
    
            hasKeys = true;
            obj[key] = this._castUpdateVal(schema, val, op, key);
          }
        }
      }
      return hasKeys;
    }
    

    Query#$where(js)

    Specifies a javascript function or expression to pass to MongoDBs query system.

    Parameters:

    Returns:

    See:

    Example

    query.$where('this.comments.length === 10 || this.name.length === 5')
    
    // or
    
    query.$where(function () {
      return this.comments.length === 10 || this.name.length === 5;
    })
    

    NOTE:

    Only use $where when you have a condition that cannot be met using other MongoDB operators like $lt.
    Be sure to read about all of its caveats before using.


    Query#all([path], val)

    Specifies an $all query condition.

    Parameters:

    See:

    When called with one argument, the most recent path passed to where() is used.


    Query#and(array)

    Specifies arguments for a $and condition.

    Parameters:

    • array <Array> array of conditions

    Returns:

    See:

    Example

    query.and([{ color: 'green' }, { status: 'ok' }])
    

    Query#batchSize(val)

    Specifies the batchSize option.

    Parameters:

    See:

    Example

    query.batchSize(100)
    

    Note

    Cannot be used with distinct()


    Query#box(val, Upper)

    Specifies a $box condition

    Parameters:

    Returns:

    See:

    Example

    var lowerLeft = [40.73083, -73.99756]
    var upperRight= [40.741404,  -73.988135]
    
    query.where('loc').within().box(lowerLeft, upperRight)
    query.box({ ll : lowerLeft, ur : upperRight })
    

    Query#canMerge(conds)

    Determines if conds can be merged using mquery().merge()

    Parameters:

    Returns:


    Query#cast(model, [obj])

    Casts this query to the schema of model

    Parameters:

    Returns:

    Note

    If obj is present, it is cast instead of this query.

    show code

    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 || '$and' === path) {
          var k = val.length
            , orComponentQuery;
    
          while (k--) {
            orComponentQuery = new Query(val[k], {}, null, this.mongooseCollection);
            orComponentQuery.cast(model);
            val[k] = orComponentQuery._conditions;
          }
    
        } else if (path === '$where') {
          type = typeof val;
    
          if ('string' !== type && 'function' !== type) {
            throw new Error("Must have a string or function for $where");
          }
    
          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 && schematype.caster.schema) {
                remainingConds = {};
                pathLastHalf = split.slice(j).join('.');
                remainingConds[pathLastHalf] = val;
                castingQuery = new Query(remainingConds, {}, null, this.mongooseCollection);
                castingQuery.cast(schematype.caster);
                obj[path] = castingQuery._conditions[pathLastHalf];
              } else {
                obj[path] = val;
              }
              continue;
            }
    
            if (utils.isObject(val)) {
              // handle geo schemas that use object notation
              // { loc: { long: Number, lat: Number }
    
              var geo = val.$near ? '$near' :
                        val.$nearSphere ? '$nearSphere' :
                        val.$within ? '$within' :
                        val.$geoIntersects ? '$geoIntersects' : '';
    
              if (!geo) {
                continue;
              }
    
              var numbertype = new Types.Number('__QueryCasting__')
              var value = val[geo];
    
              if (val.$maxDistance) {
                val.$maxDistance = numbertype.castForQuery(val.$maxDistance);
              }
    
              if ('$within' == geo) {
                var withinType = value.$center
                              || value.$centerSphere
                              || value.$box
                              || value.$polygon;
    
                if (!withinType) {
                  throw new Error('Bad $within paramater: ' + JSON.stringify(val));
                }
    
                value = withinType;
    
              } else if ('$near' == geo &&
                  'string' == typeof value.type && Array.isArray(value.coordinates)) {
                // geojson; cast the coordinates
                value = value.coordinates;
    
              } else if (('$near' == geo || '$nearSphere' == geo || '$geoIntersects' == geo) &&
                  value.$geometry && 'string' == typeof value.$geometry.type &&
                  Array.isArray(value.$geometry.coordinates)) {
                // geojson; cast the coordinates
                value = value.$geometry.coordinates;
              }
    
              ;(function _cast (val) {
                if (Array.isArray(val)) {
                  val.forEach(function (item, i) {
                    if (Array.isArray(item) || utils.isObject(item)) {
                      return _cast(item);
                    }
                    val[i] = numbertype.castForQuery(item);
                  });
                } else {
                  var nearKeys= Object.keys(val);
                  var nearLen = nearKeys.length;
                  while (nearLen--) {
                    var nkey = nearKeys[nearLen];
                    var item = val[nkey];
                    if (Array.isArray(item) || utils.isObject(item)) {
                      _cast(item);
                      val[nkey] = item;
                    } else {
                      val[nkey] = numbertype.castForQuery(item);
                    }
                  }
                }
              })(value);
            }
    
          } 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) === '$' && k !== '$id' && 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("$exists parameter must be Boolean");
                  }
                  continue;
                }
    
                if ('$type' === $cond) {
                  if ('number' !== typeof nested) {
                    throw new Error("$type parameter must be Number");
                  }
                  continue;
                }
    
                if ('$not' === $cond) {
                  this.cast(model, nested);
                } else {
                  val[$cond] = schematype.castForQuery($cond, nested);
                }
              }
            }
          } else {
            obj[path] = schematype.castForQuery(val);
          }
        }
      }
    
      return obj;
    }
    

    Query#center()

    DEPRECATED Alias for circle

    Deprecated. Use circle instead.


    Query#centerSphere([path], val)

    DEPRECATED Specifies a $centerSphere condition

    Parameters:

    Returns:

    See:

    Deprecated. Use circle instead.

    Example

    var area = { center: [50, 50], radius: 10 };
    query.where('loc').within().centerSphere(area);
    

    show code

    Query.prototype.centerSphere = function () {
      if (arguments[0] && arguments[0].constructor.name == 'Object') {
        arguments[0].spherical = true;
      }
    
      if (arguments[1] && arguments[1].constructor.name == 'Object') {
        arguments[1].spherical = true;
      }
    
      Query.base.circle.apply(this, arguments);
    }
    

    Query#circle([path], area)

    Specifies a $center or $centerSphere condition.

    Parameters:

    Returns:

    See:

    Example

    var area = { center: [50, 50], radius: 10, unique: true }
    query.where('loc').within().circle(area)
    // alternatively
    query.circle('loc', area);
    
    // spherical calculations
    var area = { center: [50, 50], radius: 10, unique: true, spherical: true }
    query.where('loc').within().circle(area)
    // alternatively
    query.circle('loc', area);
    

    New in 3.7.0


    Query#comment(val)

    Specifies the comment option.

    Parameters:

    See:

    Example

    query.comment('login query')
    

    Note

    Cannot be used with distinct()


    Query#count([criteria], [callback])

    Specifying this query as a count query.

    Parameters:

    Returns:

    See:

    Passing a callback executes the query.

    Example:

    var countQuery = model.where({ 'color': 'black' }).count();
    
    query.count({ color: 'black' }).count(callback)
    
    query.count({ color: 'black' }, callback)
    
    query.where('color', 'black').count(function (err, count) {
      if (err) return handleError(err);
      console.log('there are %d kittens', count);
    })
    

    show code

    Query.prototype.count = function (conditions, callback) {
      if ('function' == typeof conditions) {
        callback = conditions;
        conditions = undefined;
      }
    
      if (mquery.canMerge(conditions)) {
        this.merge(conditions);
      }
    
      try {
        this.cast(this.model);
      } catch (err) {
        if (callback) {
          callback(err);
        }
        return this;
      }
    
      return Query.base.count.call(this, {}, callback);
    }
    

    Query#distinct([criteria], [field], [callback])

    Declares or executes a distict() operation.

    Parameters:

    Returns:

    See:

    Passing a callback executes the query.

    Example

    distinct(criteria, field, fn)
    distinct(criteria, field)
    distinct(field, fn)
    distinct(field)
    distinct(fn)
    distinct()
    

    show code

    Query.prototype.distinct = function (conditions, field, callback) {
      if (!callback) {
        if('function' == typeof field) {
          callback = field;
          if ('string' == typeof conditions) {
            field = conditions;
            conditions = undefined;
          }
        }
    
        switch (typeof conditions) {
          case 'string':
            field = conditions;
            conditions = undefined;
            break;
          case 'function':
            callback = conditions;
            field = undefined;
            conditions = undefined;
            break;
        }
      }
    
      if (conditions instanceof Document) {
        conditions = conditions.toObject();
      }
    
      if (mquery.canMerge(conditions)) {
        this.merge(conditions)
      }
    
      try {
        this.cast(this.model);
      } catch (err) {
        if (!callback) {
          throw err;
        }
        callback(err);
        return this;
      }
    
      return Query.base.distinct.call(this, {}, field, callback);
    }
    

    Query#elemMatch(path, criteria)

    Specifies an $elemMatch condition

    Parameters:

    Returns:

    See:

    Example

    query.elemMatch('comment', { author: 'autobot', votes: {$gte: 5}})
    
    query.where('comment').elemMatch({ author: 'autobot', votes: {$gte: 5}})
    
    query.elemMatch('comment', function (elem) {
      elem.where('author').equals('autobot');
      elem.where('votes').gte(5);
    })
    
    query.where('comment').elemMatch(function (elem) {
      elem.where({ author: 'autobot' });
      elem.where('votes').gte(5);
    })
    

    Query#equals(val)

    Specifies the complementary comparison value for paths specified with where()

    Parameters:

    Returns:

    Example

    User.where('age').equals(49);
    
    // is the same as
    
    User.where('age', 49);
    

    Query#exec([operation], [callback])

    Executes the query

    Parameters:

    Returns:

    Examples:

    var promise = query.exec();
    var promise = query.exec('update');
    
    query.exec(callback);
    query.exec('find', callback);
    

    show code

    Query.prototype.exec = function exec (op, callback) {
      var promise = new Promise();
    
      if ('function' == typeof op) {
        callback = op;
        op = null;
      } else if ('string' == typeof op) {
        this.op = op;
      }
    
      if (callback) promise.addBack(callback);
    
      if (!this.op) {
        promise.complete();
        return promise;
      }
    
      Query.base.exec.call(this, op, promise.resolve.bind(promise));
    
      return promise;
    }
    

    Query#exists([path], val)

    Specifies an $exists condition

    Parameters:

    Returns:

    See:

    Example

    // { name: { $exists: true }}
    Thing.where('name').exists()
    Thing.where('name').exists(true)
    Thing.find().exists('name')
    
    // { name: { $exists: false }}
    Thing.where('name').exists(false);
    Thing.find().exists('name', false);
    

    Query#find([criteria], [callback])

    Finds documents.

    Parameters:

    Returns:

    When no callback is passed, the query is not executed.

    Example

    query.find({ name: 'Los Pollos Hermanos' }).find(callback)
    

    show code

    ``` Query.prototype.find = function (conditions, callback) { if (‘function’ == typeof conditions) {

    callback = conditions;
    conditions = {};
    

    } else if (conditions instanceof Document) {

    conditions = conditions.toObject();
    

    }

    if (mquery.canMerge(conditions)) {

    this.merge(conditions);
    

    }

    prepareDiscriminatorCriteria(this);

    try {

    this.cast(this.model);
    this._castError = null;
    

    } catch (err) {

    this._castError = err;
    

    }

    // if we don’t have a callback, then just return the query object if (!callback) {

    return Query.base.find.call(this);
    

    }

    var promise = new Promise(callback); if (this._castError) {

    promise.error(this._castError);
    return this;
    

    }

    this._applyPaths(); this._fields = this._castFields(this._fields);

    var fields = this._fieldsForExec(); var options = this._mongooseOptions; var self = this;

    return Query.base.find.call(this, {}, cb);

    function cb(err, docs) {

    if (err) return promise.error(err);
    
    if (0 === docs.length) {
      return promise.complete(docs);
    }
    
    if (!options.populate) {
      return true === options.lean
        ? promise.complete(docs)
        : completeMany(self.model, docs, fields, self, null, promise);
    }
    
    var pop = helpers.preparePopulationOptionsMQ(self, options);
    self.model.populate(docs, pop, function (err, docs) {
      if(err) return promise.error(err);
      return true === options.lean
        ? promise.complete(docs)
        : completeMany(self.model, docs, fields, self, pop, promise);
    });
  }
}
```

---

### [Query#findOne(`[criteria]`, `[projection]`, `[callback]`)](#query_Query-findOne)

Declares the query a findOne operation. When executed, the first found document is passed to the callback.

#### Parameters:

-   `[criteria]` &lt;[Object](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object), [Query](#query-js)&gt; mongodb selector
-   `[projection]` &lt;[Object](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object)&gt; optional fields to return (http://bit.ly/1HotzBo)
-   `[callback]` &lt;[Function](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function)&gt;

#### Returns:

-   &lt;[Query](#query-js)&gt; this

#### See:

-   [findOne](http://docs.mongodb.org/manual/reference/method/db.collection.findOne/ "findOne")

Passing a `callback` executes the query.

#### Example

```
var query  = Kitten.where({ color: 'white' });
query.findOne(function (err, kitten) {
  if (err) return handleError(err);
  if (kitten) {
    // doc may be null if no document matched
  }
});
```

show code

```
Query.prototype.findOne = function (conditions, projection, options, callback) {
  if ('function' == typeof conditions) {
    callback = conditions;
    conditions = null;
    projection = null;
    options = null;
  }

  if ('function' == typeof projection) {
    callback = projection;
    options = null;
    projection = null;
  }

  if ('function' == typeof options) {
    callback = options;
    options = null;
  }

  // make sure we don't send in the whole Document to merge()
  if (conditions instanceof Document) {
    conditions = conditions.toObject();
  }

  if (options) {
    this.setOptions(options);
  }

  if (projection) {
    this.select(projection);
  }

  if (mquery.canMerge(conditions)) {
    this.merge(conditions);
  }

  prepareDiscriminatorCriteria(this);

  try {
    this.cast(this.model);
    this._castError = null;
  } catch (err) {
    this._castError = err;
  }

  if (!callback) {
    // already merged in the conditions, don't need to send them in.
    return Query.base.findOne.call(this);
  }

  var promise = new Promise(callback);

  if (this._castError) {
    promise.error(this._castError);
    return this;
  }

  this._applyPaths();
  this._fields = this._castFields(this._fields);

  var options = this._mongooseOptions;
  var projection = this._fieldsForExec();
  var self = this;

  // don't pass in the conditions because we already merged them in
  Query.base.findOne.call(this, {}, function cb (err, doc) {
    if (err) return promise.error(err);
    if (!doc) return promise.complete(null);

    if (!options.populate) {
      return true === options.lean
        ? promise.complete(doc)
        : completeOne(self.model, doc, projection, self, null, promise);
    }

    var pop = helpers.preparePopulationOptionsMQ(self, options);
    self.model.populate(doc, pop, function (err, doc) {
      if (err) return promise.error(err);

      return true === options.lean
        ? promise.complete(doc)
        : completeOne(self.model, doc, projection, self, pop, promise);
    });
  })

  return this;
}
```

---

### [Query#findOneAndRemove(`[conditions]`, `[options]`, `[callback]`)](#query_Query-findOneAndRemove)

Issues a mongodb [findAndModify](http://www.mongodb.org/display/DOCS/findAndModify+Command) remove command.

#### Parameters:

-   `[conditions]` &lt;[Object](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object)&gt;
-   `[options]` &lt;[Object](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object)&gt;
-   `[callback]` &lt;[Function](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function)&gt;

#### Returns:

-   &lt;[Query](#query-js)&gt; this

#### See:

-   [mongodb](http://www.mongodb.org/display/DOCS/findAndModify+Command "mongodb")

Finds a matching document, removes it, passing the found document (if any) to the callback. Executes immediately if `callback` is passed.

#### Available options

-   `sort`: if multiple docs are found by the conditions, sets the sort order to choose which doc to update

#### Examples

```
A.where().findOneAndRemove(conditions, options, callback) // executes
A.where().findOneAndRemove(conditions, options)  // return Query
A.where().findOneAndRemove(conditions, callback) // executes
A.where().findOneAndRemove(conditions) // returns Query
A.where().findOneAndRemove(callback)   // executes
A.where().findOneAndRemove()           // returns Query
```

---

### [Query#findOneAndUpdate(`[query]`, `[doc]`, `[options]`, `[callback]`)](#query_Query-findOneAndUpdate)

Issues a mongodb [findAndModify](http://www.mongodb.org/display/DOCS/findAndModify+Command) update command.

#### Parameters:

-   `[query]` &lt;[Object](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object), [Query](#query-js)&gt;
-   `[doc]` &lt;[Object](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object)&gt;
-   `[options]` &lt;[Object](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object)&gt;
-   `[callback]` &lt;[Function](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function)&gt;

#### Returns:

-   &lt;[Query](#query-js)&gt; this

#### See:

-   [mongodb](http://www.mongodb.org/display/DOCS/findAndModify+Command "mongodb")

Finds a matching document, updates it according to the `update` arg, passing any `options`, and returns the found document (if any) to the callback. The query executes immediately if `callback` is passed.

#### Available options

-   `new`: bool - true to return the modified document rather than the original. defaults to true
-   `upsert`: bool - creates the object if it doesn't exist. defaults to false.
-   `sort`: if multiple docs are found by the conditions, sets the sort order to choose which doc to update

#### Examples

```
query.findOneAndUpdate(conditions, update, options, callback) // executes
query.findOneAndUpdate(conditions, update, options)  // returns Query
query.findOneAndUpdate(conditions, update, callback) // executes
query.findOneAndUpdate(conditions, update)           // returns Query
query.findOneAndUpdate(update, callback)             // returns Query
query.findOneAndUpdate(update)                       // returns Query
query.findOneAndUpdate(callback)                     // executes
query.findOneAndUpdate()                             // returns Query
```

---

### [Query#geometry(`object`)](#query_Query-geometry)

Specifies a `$geometry` condition

#### Parameters:

-   `object` &lt;[Object](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object)&gt; Must contain a \`type\` property which is a String and a \`coordinates\` property which is an Array. See the examples.

#### Returns:

-   &lt;[Query](#query-js)&gt; this

#### See:

-   [$geometry](http://docs.mongodb.org/manual/reference/operator/geometry/ "$geometry")
-   [http://docs.mongodb.org/manual/release-notes/2.4/#new-geospatial-indexes-with-geojson-and-improved-spherical-geometry](http://docs.mongodb.org/manual/release-notes/2.4/#new-geospatial-indexes-with-geojson-and-improved-spherical-geometry)
-   [http://www.mongodb.org/display/DOCS/Geospatial+Indexing](http://www.mongodb.org/display/DOCS/Geospatial+Indexing)

#### Example

```
var polyA = [[[ 10, 20 ], [ 10, 40 ], [ 30, 40 ], [ 30, 20 ]]]
query.where('loc').within().geometry({ type: 'Polygon', coordinates: polyA })

// or
var polyB = [[ 0, 0 ], [ 1, 1 ]]
query.where('loc').within().geometry({ type: 'LineString', coordinates: polyB })

// or
var polyC = [ 0, 0 ]
query.where('loc').within().geometry({ type: 'Point', coordinates: polyC })

// or
query.where('loc').intersects().geometry({ type: 'Point', coordinates: polyC })
```

The argument is assigned to the most recent path passed to `where()`.

#### NOTE:

`geometry()` **must** come after either `intersects()` or `within()`.

The `object` argument must contain `type` and `coordinates` properties.  
\- type {String}  
\- coordinates {Array}

---

### [Query#gt(`[path]`, `val`)](#query_Query-gt)

Specifies a $gt query condition.

#### Parameters:

-   `[path]` &lt;[String](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String)&gt;
-   `val` &lt;[Number](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Number)&gt;

#### See:

-   [$gt](http://docs.mongodb.org/manual/reference/operator/gt/ "$gt")

When called with one argument, the most recent path passed to `where()` is used.

#### Example

```
Thing.find().where('age').gt(21)

// or
Thing.find().gt('age', 21)
```

---

### [Query#gte(`[path]`, `val`)](#query_Query-gte)

Specifies a $gte query condition.

#### Parameters:

-   `[path]` &lt;[String](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String)&gt;
-   `val` &lt;[Number](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Number)&gt;

#### See:

-   [$gte](http://docs.mongodb.org/manual/reference/operator/gte/ "$gte")

When called with one argument, the most recent path passed to `where()` is used.

---

### [Query#hint(`val`)](#query_Query-hint)

Sets query hints.

#### Parameters:

-   `val` &lt;[Object](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object)&gt; a hint object

#### Returns:

-   &lt;[Query](#query-js)&gt; this

#### See:

-   [$hint](http://docs.mongodb.org/manual/reference/operator/hint/ "$hint")

#### Example

```
query.hint({ indexA: 1, indexB: -1})
```

#### Note

Cannot be used with `distinct()`

---

### [Query#in(`[path]`, `val`)](#query_Query-in)

Specifies an $in query condition.

#### Parameters:

-   `[path]` &lt;[String](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String)&gt;
-   `val` &lt;[Number](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Number)&gt;

#### See:

-   [$in](http://docs.mongodb.org/manual/reference/operator/in/ "$in")

When called with one argument, the most recent path passed to `where()` is used.

---

### [Query#intersects(`[arg]`)](#query_Query-intersects)

Declares an intersects query for `geometry()`.

#### Parameters:

-   `[arg]` &lt;[Object](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object)&gt;

#### Returns:

-   &lt;[Query](#query-js)&gt; this

#### See:

-   [$geometry](http://docs.mongodb.org/manual/reference/operator/geometry/ "$geometry")
-   [geoIntersects](http://docs.mongodb.org/manual/reference/operator/geoIntersects/ "geoIntersects")

#### Example

```
query.where('path').intersects().geometry({
    type: 'LineString'
  , coordinates: [[180.0, 11.0], [180, 9.0]]
})

query.where('path').intersects({
    type: 'LineString'
  , coordinates: [[180.0, 11.0], [180, 9.0]]
})
```

#### NOTE:

**MUST** be used after `where()`.

#### NOTE:

In Mongoose 3.7, `intersects` changed from a getter to a function. If you need the old syntax, use [this](https://github.com/ebensing/mongoose-within).

---

### [Query#lean(`bool`)](#query_Query-lean)

Sets the lean option.

#### Parameters:

-   `bool` &lt;[Boolean](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Boolean)&gt; defaults to true

#### Returns:

-   &lt;[Query](#query-js)&gt; this

Documents returned from queries with the `lean` option enabled are plain javascript objects, not [MongooseDocuments](#document-js). They have no `save` method, getters/setters or other Mongoose magic applied.

#### Example:

```
new Query().lean() // true
new Query().lean(true)
new Query().lean(false)

Model.find().lean().exec(function (err, docs) {
  docs[0] instanceof mongoose.Document // false
});
```

This is a [great](https://groups.google.com/forum/#!topic/mongoose-orm/u2_DzDydcnA/discussion) option in high-performance read-only scenarios, especially when combined with [stream](#query_Query-stream).

show code

```
Query.prototype.lean = function (v) {
  this._mongooseOptions.lean = arguments.length ? !!v : true;
  return this;
}
```

---

### [Query#limit(`val`)](#query_Query-limit)

Specifies the maximum number of documents the query will return.

#### Parameters:

-   `val` &lt;[Number](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Number)&gt;

#### Example

```
query.limit(20)
```

#### Note

Cannot be used with `distinct()`

---

### [Query#lt(`[path]`, `val`)](#query_Query-lt)

Specifies a $lt query condition.

#### Parameters:

-   `[path]` &lt;[String](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String)&gt;
-   `val` &lt;[Number](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Number)&gt;

#### See:

-   [$lt](http://docs.mongodb.org/manual/reference/operator/lt/ "$lt")

When called with one argument, the most recent path passed to `where()` is used.

---

### [Query#lte(`[path]`, `val`)](#query_Query-lte)

Specifies a $lte query condition.

#### Parameters:

-   `[path]` &lt;[String](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String)&gt;
-   `val` &lt;[Number](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Number)&gt;

#### See:

-   [$lte](http://docs.mongodb.org/manual/reference/operator/lte/ "$lte")

When called with one argument, the most recent path passed to `where()` is used.

---

### [Query#maxDistance(`[path]`, `val`)](#query_Query-maxDistance)

Specifies a $maxDistance query condition.

#### Parameters:

-   `[path]` &lt;[String](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String)&gt;
-   `val` &lt;[Number](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Number)&gt;

#### See:

-   [$maxDistance](http://docs.mongodb.org/manual/reference/operator/maxDistance/ "$maxDistance")

When called with one argument, the most recent path passed to `where()` is used.

---

### [Query#maxscan()](#query_Query-maxscan)

*DEPRECATED* Alias of `maxScan`

#### See:

-   [maxScan](#query_Query-maxScan "maxScan")

---

### [Query#maxScan(`val`)](#query_Query-maxScan)

Specifies the maxScan option.

#### Parameters:

-   `val` &lt;[Number](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Number)&gt;

#### See:

-   [maxScan](http://docs.mongodb.org/manual/reference/operator/maxScan/ "maxScan")

#### Example

```
query.maxScan(100)
```

#### Note

Cannot be used with `distinct()`

---

### [Query#merge(`source`)](#query_Query-merge)

Merges another Query or conditions object into this one.

#### Parameters:

-   `source` &lt;[Query](#query-js), [Object](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object)&gt;

#### Returns:

-   &lt;[Query](#query-js)&gt; this

When a Query is passed, conditions, field selection and options are merged.

New in 3.7.0

---

### [Query#mod(`[path]`, `val`)](#query_Query-mod)

Specifies a `$mod` condition

#### Parameters:

-   `[path]` &lt;[String](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String)&gt;
-   `val` &lt;[Number](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Number)&gt;

#### Returns:

-   &lt;[Query](#query-js)&gt; this

#### See:

-   [$mod](http://docs.mongodb.org/manual/reference/operator/mod/ "$mod")

---

### [Query#ne(`[path]`, `val`)](#query_Query-ne)

Specifies a $ne query condition.

#### Parameters:

-   `[path]` &lt;[String](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String)&gt;
-   `val` &lt;[Number](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Number)&gt;

#### See:

-   [$ne](http://docs.mongodb.org/manual/reference/operator/ne/ "$ne")

When called with one argument, the most recent path passed to `where()` is used.

---

### [Query#near(`[path]`, `val`)](#query_Query-near)

Specifies a `$near` or `$nearSphere` condition

#### Parameters:

-   `[path]` &lt;[String](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String)&gt;
-   `val` &lt;[Object](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object)&gt;

#### Returns:

-   &lt;[Query](#query-js)&gt; this

#### See:

-   [$near](http://docs.mongodb.org/manual/reference/operator/near/ "$near")
-   [$nearSphere](http://docs.mongodb.org/manual/reference/operator/nearSphere/ "$nearSphere")
-   [$maxDistance](http://docs.mongodb.org/manual/reference/operator/maxDistance/ "$maxDistance")
-   [http://www.mongodb.org/display/DOCS/Geospatial+Indexing](http://www.mongodb.org/display/DOCS/Geospatial+Indexing)

These operators return documents sorted by distance.

#### Example

```
query.where('loc').near({ center: [10, 10] });
query.where('loc').near({ center: [10, 10], maxDistance: 5 });
query.where('loc').near({ center: [10, 10], maxDistance: 5, spherical: true });
query.near('loc', { center: [10, 10], maxDistance: 5 });
```

---

### [Query#nearSphere()](#query_Query-nearSphere)

*DEPRECATED* Specifies a `$nearSphere` condition

#### See:

-   [near()](#query_Query-near "near()")
-   [$near](http://docs.mongodb.org/manual/reference/operator/near/ "$near")
-   [$nearSphere](http://docs.mongodb.org/manual/reference/operator/nearSphere/ "$nearSphere")
-   [$maxDistance](http://docs.mongodb.org/manual/reference/operator/maxDistance/ "$maxDistance")

#### Example

```
query.where('loc').nearSphere({ center: [10, 10], maxDistance: 5 });
```

**Deprecated.** Use `query.near()` instead with the `spherical` option set to `true`.

#### Example

```
query.where('loc').near({ center: [10, 10], spherical: true });
```

show code

```
Query.prototype.nearSphere = function () {
  this._mongooseOptions.nearSphere = true;
  this.near.apply(this, arguments);
  return this;
}
```

---

### [Query#nin(`[path]`, `val`)](#query_Query-nin)

Specifies an $nin query condition.

#### Parameters:

-   `[path]` &lt;[String](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String)&gt;
-   `val` &lt;[Number](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Number)&gt;

#### See:

-   [$nin](http://docs.mongodb.org/manual/reference/operator/nin/ "$nin")

When called with one argument, the most recent path passed to `where()` is used.

---

### [Query#nor(`array`)](#query_Query-nor)

Specifies arguments for a `$nor` condition.

#### Parameters:

-   `array` &lt;[Array](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array)&gt; array of conditions

#### Returns:

-   &lt;[Query](#query-js)&gt; this

#### See:

-   [$nor](http://docs.mongodb.org/manual/reference/operator/nor/ "$nor")

#### Example

```
query.nor([{ color: 'green' }, { status: 'ok' }])
```

---

### [Query#or(`array`)](#query_Query-or)

Specifies arguments for an `$or` condition.

#### Parameters:

-   `array` &lt;[Array](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array)&gt; array of conditions

#### Returns:

-   &lt;[Query](#query-js)&gt; this

#### See:

-   [$or](http://docs.mongodb.org/manual/reference/operator/or/ "$or")

#### Example

```
query.or([{ color: 'red' }, { status: 'emergency' }])
```

---

### [Query#polygon(`[path]`, `[coordinatePairs...]`)](#query_Query-polygon)

Specifies a $polygon condition

#### Parameters:

-   `[path]` &lt;[String](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String), [Array](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array)&gt;
-   `[coordinatePairs...]` &lt;[Array](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array), [Object](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object)&gt;

#### Returns:

-   &lt;[Query](#query-js)&gt; this

#### See:

-   [$polygon](http://docs.mongodb.org/manual/reference/operator/polygon/ "$polygon")
-   [http://www.mongodb.org/display/DOCS/Geospatial+Indexing](http://www.mongodb.org/display/DOCS/Geospatial+Indexing)

#### Example

```
query.where('loc').within().polygon([10,20], [13, 25], [7,15])
query.polygon('loc', [10,20], [13, 25], [7,15])
```

---

### [Query#populate(`path`, `[select]`, `[model]`, `[match]`, `[options]`)](#query_Query-populate)

Specifies paths which should be populated with other documents.

#### Parameters:

-   `path` &lt;[Object](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object), [String](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String)&gt; either the path to populate or an object specifying all parameters
-   `[select]` &lt;[Object](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object), [String](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String)&gt; Field selection for the population query
-   `[model]` &lt;[Model](#model_Model)&gt; The name of the model you wish to use for population. If not specified, the name is looked up from the Schema ref.
-   `[match]` &lt;[Object](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object)&gt; Conditions for the population query
-   `[options]` &lt;[Object](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object)&gt; Options for the population query (sort, etc)

#### Returns:

-   &lt;[Query](#query-js)&gt; this

#### See:

-   [population]($2ca59dedcf97b3b3.md "population")
-   [Query#select](#query_Query-select "Query#select")
-   [Model.populate](#model_Model.populate "Model.populate")

#### Example:

```
Kitten.findOne().populate('owner').exec(function (err, kitten) {
  console.log(kitten.owner.name) // Max
})

Kitten.find().populate({
    path: 'owner'
  , select: 'name'
  , match: { color: 'black' }
  , options: { sort: { name: -1 }}
}).exec(function (err, kittens) {
  console.log(kittens[0].owner.name) // Zoopa
})

// alternatively
Kitten.find().populate('owner', 'name', null, {sort: { name: -1 }}).exec(function (err, kittens) {
  console.log(kittens[0].owner.name) // Zoopa
})
```

Paths are populated after the query executes and a response is received. A separate query is then executed for each path specified for population. After a response for each query has also been returned, the results are passed to the callback.

show code

```
Query.prototype.populate = function () {
  var res = utils.populate.apply(null, arguments);
  var opts = this._mongooseOptions;

  if (!utils.isObject(opts.populate)) {
    opts.populate = {};
  }

  for (var i = 0; i < res.length; ++i) {
    opts.populate[res[i].path] = res[i];
  }

  return this;
}
```

---

### [Query(`[options]`, `[model]`, `[conditions]`, `[collection]`)](#query_Query)

Query constructor used for building queries.

#### Parameters:

-   `[options]` &lt;[Object](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object)&gt;
-   `[model]` &lt;[Object](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object)&gt;
-   `[conditions]` &lt;[Object](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object)&gt;
-   `[collection]` &lt;[Object](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object)&gt; Mongoose collection

#### Example:

```
var query = new Query();
query.setOptions({ lean : true });
query.collection(model.collection);
query.where('age').gte(21).exec(callback);
```

show code

```
function Query(conditions, options, model, collection) {
  // this stuff is for dealing with custom queries created by #toConstructor
  if (!this._mongooseOptions) {
    this._mongooseOptions = {};
  }

  // this is the case where we have a CustomQuery, we need to check if we got
  // options passed in, and if we did, merge them in
  if (options) {
    var keys = Object.keys(options);
    for (var i=0; i < keys.length; i++) {
      var k = keys[i];
      this._mongooseOptions[k] = options[k];
    }
  }

  if (collection) {
    this.mongooseCollection = collection;
  }

  if (model) {
    this.model = model;
  }

  // this is needed because map reduce returns a model that can be queried, but
  // all of the queries on said model should be lean
  if (this.model && this.model._mapreduce) {
    this.lean();
  }

  // inherit mquery
  mquery.call(this, this.mongooseCollection, options);

  if (conditions) {
    this.find(conditions);
  }
}
```

---

### [Query#read(`pref`, `[tags]`)](#query_Query-read)

Determines the MongoDB nodes from which to read.

#### Parameters:

-   `pref` &lt;[String](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String)&gt; one of the listed preference options or aliases
-   `[tags]` &lt;[Array](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array)&gt; optional tags for this query

#### Returns:

-   &lt;[Query](#query-js)&gt; this

#### See:

-   [mongodb](http://docs.mongodb.org/manual/applications/replication/#read-preference "mongodb")
-   [driver](http://mongodb.github.com/node-mongodb-native/driver-articles/anintroductionto1_1and2_2.html#read-preferences "driver")

#### Preferences:

```
primary - (default) Read from primary only. Operations will produce an error if primary is unavailable. Cannot be combined with tags.
secondary            Read from secondary if available, otherwise error.
primaryPreferred     Read from primary if available, otherwise a secondary.
secondaryPreferred   Read from a secondary if available, otherwise read from the primary.
nearest              All operations read from among the nearest candidates, but unlike other modes, this option will include both the primary and all secondaries in the random selection.
```

Aliases

```
p   primary
pp  primaryPreferred
s   secondary
sp  secondaryPreferred
n   nearest
```

#### Example:

```
new Query().read('primary')
new Query().read('p')  // same as primary

new Query().read('primaryPreferred')
new Query().read('pp') // same as primaryPreferred

new Query().read('secondary')
new Query().read('s')  // same as secondary

new Query().read('secondaryPreferred')
new Query().read('sp') // same as secondaryPreferred

new Query().read('nearest')
new Query().read('n')  // same as nearest

// read from secondaries with matching tags
new Query().read('s', [{ dc:'sf', s: 1 },{ dc:'ma', s: 2 }])
```

Read more about how to use read preferrences [here](http://docs.mongodb.org/manual/applications/replication/#read-preference) and [here](http://mongodb.github.com/node-mongodb-native/driver-articles/anintroductionto1_1and2_2.html#read-preferences).

---

### [Query#regex(`[path]`, `val`)](#query_Query-regex)

Specifies a $regex query condition.

#### Parameters:

-   `[path]` &lt;[String](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String)&gt;
-   `val` &lt;[Number](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Number)&gt;

#### See:

-   [$regex](http://docs.mongodb.org/manual/reference/operator/regex/ "$regex")

When called with one argument, the most recent path passed to `where()` is used.

---

### [Query#remove(`[criteria]`, `[callback]`)](#query_Query-remove)

Declare and/or execute this query as a remove() operation.

#### Parameters:

-   `[criteria]` &lt;[Object](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object), [Query](#query-js)&gt; mongodb selector
-   `[callback]` &lt;[Function](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function)&gt;

#### Returns:

-   &lt;[Query](#query-js)&gt; this

#### See:

-   [remove](http://docs.mongodb.org/manual/reference/method/db.collection.remove/ "remove")

#### Example

```
Model.remove({ artist: 'Anne Murray' }, callback)
```

#### Note

The operation is only executed when a callback is passed. To force execution without a callback (which would be an unsafe write), we must first call remove() and then execute it by using the `exec()` method.

```
// not executed
var query = Model.find().remove({ name: 'Anne Murray' })

// executed
query.remove({ name: 'Anne Murray' }, callback)
query.remove({ name: 'Anne Murray' }).remove(callback)

// executed without a callback (unsafe write)
query.exec()

// summary
query.remove(conds, fn); // executes
query.remove(conds)
query.remove(fn) // executes
query.remove()
```

show code

```
Query.prototype.remove = function (cond, callback) {
  if ('function' == typeof cond) {
    callback = cond;
    cond = null;
  }

  var cb = 'function' == typeof callback;

  try {
    this.cast(this.model);
  } catch (err) {
    if (cb) return process.nextTick(callback.bind(null, err));
    return this;
  }

  return Query.base.remove.call(this, cond, callback);
}
```

---

### [Query#select(`arg`)](#query_Query-select)

Specifies which document fields to include or exclude (also known as the query "projection")

#### Parameters:

-   `arg` &lt;[Object](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object), [String](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String)&gt;

#### Returns:

-   &lt;[Query](#query-js)&gt; this

#### See:

-   [SchemaType](#schematype_SchemaType "SchemaType")

When using string syntax, prefixing a path with `-` will flag that path as excluded. When a path does not have the `-` prefix, it is included. Lastly, if a path is prefixed with `+`, it forces inclusion of the path, which is useful for paths excluded at the [schema level](https://mongoosejs.com/docs/api.html#schematype_SchemaType-select).

#### Example

```
// include a and b, exclude other fields
query.select('a b');

// exclude c and d, include other fields
query.select('-c -d');

// or you may use object notation, useful when
// you have keys already prefixed with a "-"
query.select({ a: 1, b: 1 });
query.select({ c: 0, d: 0 });

// force inclusion of field excluded at schema level
query.select('+path')
```

#### NOTE:

Cannot be used with `distinct()`.

*v2 had slightly different syntax such as allowing arrays of field names. This support was removed in v3.*

---

### [Query#setOptions(`options`)](#query_Query-setOptions)

Sets query options.

#### Parameters:

-   `options` &lt;[Object](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object)&gt;

#### Options:

-   [tailable](http://www.mongodb.org/display/DOCS/Tailable+Cursors) \*
-   [sort](http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%7B%7Bsort()%7D%7D) \*
-   [limit](http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%7B%7Blimit%28%29%7D%7D) \*
-   [skip](http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%7B%7Bskip%28%29%7D%7D) \*
-   [maxscan](http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24maxScan) \*
-   [batchSize](http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%7B%7BbatchSize%28%29%7D%7D) \*
-   [comment](http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24comment) \*
-   [snapshot](http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%7B%7Bsnapshot%28%29%7D%7D) \*
-   [hint](http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24hint) \*
-   [slaveOk](http://docs.mongodb.org/manual/applications/replication/#read-preference) \*
-   [lean]($eef6a27794618837.md#query_Query-lean) \*
-   [safe](http://www.mongodb.org/display/DOCS/getLastError+Command)

*\* denotes a query helper method is also available*

show code

```
Query.prototype.setOptions = function (options, overwrite) {
  // overwrite is only for internal use
  if (overwrite) {
    // ensure that _mongooseOptions & options are two different objects
    this._mongooseOptions = (options && utils.clone(options)) || {};
    this.options = options || {};

    if('populate' in options) {
      this.populate(this._mongooseOptions);
    }
    return this;
  }

  if (!(options && 'Object' == options.constructor.name)) {
    return this;
  }

  return Query.base.setOptions.call(this, options);
}
```

---

### [Query#size(`[path]`, `val`)](#query_Query-size)

Specifies a $size query condition.

#### Parameters:

-   `[path]` &lt;[String](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String)&gt;
-   `val` &lt;[Number](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Number)&gt;

#### See:

-   [$size](http://docs.mongodb.org/manual/reference/operator/size/ "$size")

When called with one argument, the most recent path passed to `where()` is used.

#### Example

```
MyModel.where('tags').size(0).exec(function (err, docs) {
  if (err) return handleError(err);

  assert(Array.isArray(docs));
  console.log('documents with 0 tags', docs);
})
```

---

### [Query#skip(`val`)](#query_Query-skip)

Specifies the number of documents to skip.

#### Parameters:

-   `val` &lt;[Number](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Number)&gt;

#### See:

-   [cursor.skip](http://docs.mongodb.org/manual/reference/method/cursor.skip/ "cursor.skip")

#### Example

```
query.skip(100).limit(20)
```

#### Note

Cannot be used with `distinct()`

---

### [Query#slaveOk(`v`)](#query_Query-slaveOk)

*DEPRECATED* Sets the slaveOk option.

#### Parameters:

-   `v` &lt;[Boolean](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Boolean)&gt; defaults to true

#### Returns:

-   &lt;[Query](#query-js)&gt; this

#### See:

-   [mongodb](http://docs.mongodb.org/manual/applications/replication/#read-preference "mongodb")
-   [slaveOk](http://docs.mongodb.org/manual/reference/method/rs.slaveOk/ "slaveOk")
-   [read()](#query_Query-read "read()")

**Deprecated** in MongoDB 2.2 in favor of [read preferences](#query_Query-read).

#### Example:

```
query.slaveOk() // true
query.slaveOk(true)
query.slaveOk(false)
```

---

### [Query#slice(`[path]`, `val`)](#query_Query-slice)

Specifies a $slice projection for an array.

#### Parameters:

-   `[path]` &lt;[String](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String)&gt;
-   `val` &lt;[Number](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Number)&gt; number/range of elements to slice

#### Returns:

-   &lt;[Query](#query-js)&gt; this

#### See:

-   [mongodb](http://www.mongodb.org/display/DOCS/Retrieving+a+Subset+of+Fields#RetrievingaSubsetofFields-RetrievingaSubrangeofArrayElements "mongodb")
-   [$slice](http://docs.mongodb.org/manual/reference/projection/slice/#prj._S_slice "$slice")

#### Example

```
query.slice('comments', 5)
query.slice('comments', -5)
query.slice('comments', [10, 5])
query.where('comments').slice(5)
query.where('comments').slice([-10, 5])
```

---

### [Query#snapshot()](#query_Query-snapshot)

Specifies this query as a `snapshot` query.

#### Returns:

-   &lt;[Query](#query-js)&gt; this

#### See:

-   [snapshot](http://docs.mongodb.org/manual/reference/operator/snapshot/ "snapshot")

#### Example

```
query.snapshot() // true
query.snapshot(true)
query.snapshot(false)
```

#### Note

Cannot be used with `distinct()`

---

### [Query#sort(`arg`)](#query_Query-sort)

Sets the sort order

#### Parameters:

-   `arg` &lt;[Object](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object), [String](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String)&gt;

#### Returns:

-   &lt;[Query](#query-js)&gt; this

#### See:

-   [cursor.sort](http://docs.mongodb.org/manual/reference/method/cursor.sort/ "cursor.sort")

If an object is passed, values allowed are `asc`, `desc`, `ascending`, `descending`, `1`, and `-1`.

If a string is passed, it must be a space delimited list of path names. The  
sort order of each path is ascending unless the path name is prefixed with `-`  
which will be treated as descending.

#### Example

```
// sort by "field" ascending and "test" descending
query.sort({ field: 'asc', test: -1 });

// equivalent
query.sort('field -test');
```

#### Note

Cannot be used with `distinct()`

show code

```
Query.prototype.sort = function (arg) {
  var nArg = {};

  if (arguments.length > 1) {
    throw new Error("sort() only takes 1 Argument");
  }

  if (Array.isArray(arg)) {
    // time to deal with the terrible syntax
    for (var i=0; i < arg.length; i++) {
      if (!Array.isArray(arg[i])) throw new Error("Invalid sort() argument.");
      nArg[arg[i][0]] = arg[i][1];
    }

  } else {
    nArg = arg;
  }

  return Query.base.sort.call(this, nArg);
}
```

---

### [Query#stream(`[options]`)](#query_Query-stream)

Returns a Node.js 0.8 style [read stream](http://nodejs.org/docs/v0.8.21/api/stream.html#stream_readable_stream) interface.

#### Parameters:

-   `[options]` &lt;[Object](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object)&gt;

#### Returns:

-   &lt;[QueryStream](#querystream_QueryStream)&gt;

#### See:

-   [QueryStream](#querystream_QueryStream "QueryStream")

#### Example

```
// follows the nodejs 0.8 stream api
Thing.find({ name: /^hello/ }).stream().pipe(res)

// manual streaming
var stream = Thing.find({ name: /^hello/ }).stream();

stream.on('data', function (doc) {
  // do something with the mongoose document
}).on('error', function (err) {
  // handle the error
}).on('close', function () {
  // the stream is closed
});
```

#### Valid options

-   `transform`: optional function which accepts a mongoose document. The return value of the function will be emitted on `data`.

#### Example

```
// JSON.stringify all documents before emitting
var stream = Thing.find().stream({ transform: JSON.stringify });
stream.pipe(writeStream);
```

show code

```
Query.prototype.stream = function stream (opts) {
  this._applyPaths();
  this._fields = this._castFields(this._fields);
  return new QueryStream(this, opts);
}

// the rest of these are basically to support older Mongoose syntax with mquery
```

---

### [Query#tailable(`bool`)](#query_Query-tailable)

Sets the tailable option (for use with capped collections).

#### Parameters:

-   `bool` &lt;[Boolean](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Boolean)&gt; defaults to true

#### See:

-   [tailable](http://docs.mongodb.org/manual/tutorial/create-tailable-cursor/ "tailable")

#### Example

```
query.tailable() // true
query.tailable(true)
query.tailable(false)
```

#### Note

Cannot be used with `distinct()`

show code

```
Query.prototype.tailable = function (val, opts) {
  // we need to support the tailable({ awaitdata : true }) as well as the
  // tailable(true, {awaitdata :true}) syntax that mquery does not support
  if (val && val.constructor.name == 'Object') {
    opts = val;
    val = true;
  }

  if (val === undefined) {
    val = true;
  }

  if (opts && typeof opts === 'object') {
    for (var key in opts) {
      if (key === 'awaitdata') {
        // For backwards compatibility
        this.options[key] = !!opts[key];
      } else {
        this.options[key] = opts[key];
      }
    }
  }

  return Query.base.tailable.call(this, val);
}
```

---

### [Query#toConstructor()](#query_Query-toConstructor)

Converts this query to a customized, reusable query constructor with all arguments and options retained.

#### Returns:

-   &lt;[Query](#query-js)&gt; subclass-of-Query

#### Example

```
// Create a query for adventure movies and read from the primary
// node in the replica-set unless it is down, in which case we'll
// read from a secondary node.
var query = Movie.find({ tags: 'adventure' }).read('primaryPreferred');

// create a custom Query constructor based off these settings
var Adventure = query.toConstructor();

// Adventure is now a subclass of mongoose.Query and works the same way but with the
// default query parameters and options set.
Adventure().exec(callback)

// further narrow down our query results while still using the previous settings
Adventure().where({ name: /^Life/ }).exec(callback);

// since Adventure is a stand-alone constructor we can also add our own
// helper methods and getters without impacting global queries
Adventure.prototype.startsWith = function (prefix) {
  this.where({ name: new RegExp('^' + prefix) })
  return this;
}
Object.defineProperty(Adventure.prototype, 'highlyRated', {
  get: function () {
    this.where({ rating: { $gt: 4.5 }});
    return this;
  }
})
Adventure().highlyRated.startsWith('Life').exec(callback)
```

New in 3.7.3

show code

```
Query.prototype.toConstructor = function toConstructor () {
  function CustomQuery (criteria, options) {
    if (!(this instanceof CustomQuery))
      return new CustomQuery(criteria, options);
    Query.call(this, criteria, options || null);
  }

  util.inherits(CustomQuery, Query);

  // set inherited defaults
  var p = CustomQuery.prototype;

  p.options = {};

  p.setOptions(this.options);

  p.op = this.op;
  p._conditions = utils.clone(this._conditions);
  p._fields = utils.clone(this._fields);
  p._update = utils.clone(this._update);
  p._path = this._path;
  p._distict = this._distinct;
  p._collection = this._collection;
  p.model = this.model;
  p.mongooseCollection = this.mongooseCollection;
  p._mongooseOptions = this._mongooseOptions;

  return CustomQuery;
}
```

---

### [Query#update(`[criteria]`, `[doc]`, `[options]`, `[callback]`)](#query_Query-update)

Declare and/or execute this query as an update() operation.

#### Parameters:

-   `[criteria]` &lt;[Object](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object)&gt;
-   `[doc]` &lt;[Object](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object)&gt; the update command
-   `[options]` &lt;[Object](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object)&gt;
-   `[callback]` &lt;[Function](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function)&gt;

#### Returns:

-   &lt;[Query](#query-js)&gt; this

#### See:

-   [Model.update](#model_Model.update "Model.update")
-   [update](http://docs.mongodb.org/manual/reference/method/db.collection.update/ "update")

*All paths passed that are not $atomic operations will become $set ops.*

#### Example

```
Model.where({ _id: id }).update({ title: 'words' })

// becomes

Model.where({ _id: id }).update({ $set: { title: 'words' }})
```

#### Note

Passing an empty object `{}` as the doc will result in a no-op unless the `overwrite` option is passed. Without the `overwrite` option set, the update operation will be ignored and the callback executed without sending the command to MongoDB so as to prevent accidently overwritting documents in the collection.

#### Note

The operation is only executed when a callback is passed. To force execution without a callback (which would be an unsafe write), we must first call update() and then execute it by using the `exec()` method.

```
var q = Model.where({ _id: id });
q.update({ $set: { name: 'bob' }}).update(); // not executed

q.update({ $set: { name: 'bob' }}).exec(); // executed as unsafe

// keys that are not $atomic ops become $set.
// this executes the same command as the previous example.
q.update({ name: 'bob' }).exec();

// overwriting with empty docs
var q = Model.where({ _id: id }).setOptions({ overwrite: true })
q.update({ }, callback); // executes

// multi update with overwrite to empty doc
var q = Model.where({ _id: id });
q.setOptions({ multi: true, overwrite: true })
q.update({ });
q.update(callback); // executed

// multi updates
Model.where()
     .update({ name: /^match/ }, { $set: { arr: [] }}, { multi: true }, callback)

// more multi updates
Model.where()
     .setOptions({ multi: true })
     .update({ $set: { arr: [] }}, callback)

// single update by default
Model.where({ email: 'address@example.com' })
     .update({ $inc: { counter: 1 }}, callback)
```

API summary

```
update(criteria, doc, options, cb) // executes
update(criteria, doc, options)
update(criteria, doc, cb) // executes
update(criteria, doc)
update(doc, cb) // executes
update(doc)
update(cb) // executes
update(true) // executes (unsafe write)
update()
```

show code

```
Query.prototype.update = function (conditions, doc, options, callback) {
  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;
  } else if ('function' === typeof conditions) {
    callback = conditions;
    conditions = undefined;
    doc = undefined;
    options = undefined;
  }

  // make sure we don't send in the whole Document to merge()
  if (conditions instanceof Document) {
    conditions = conditions.toObject();
  }

  // strict is an option used in the update checking, make sure it gets set
  if (options) {
    if ('strict' in options) {
      this._mongooseOptions.strict = options.strict;
    }
  }

  // if doc is undefined at this point, this means this function is being
  // executed by exec(not always see below). Grab the update doc from here in
  // order to validate
  // This could also be somebody calling update() or update({}). Probably not a
  // common use case, check for _update to make sure we don't do anything bad
  if (!doc && this._update) {
    doc = this._updateForExec();
  }

  if (mquery.canMerge(conditions)) {
    this.merge(conditions);
  }

  // validate the selector part of the query
  var castedQuery = castQuery(this);
  if (castedQuery instanceof Error) {
    if(callback) {
      callback(castedQuery);
      return this;
    } else {
      throw castedQuery;
    }
  }

  // validate the update part of the query
  var castedDoc;
  try {
    castedDoc = this._castUpdate(utils.clone(doc, { retainKeyOrder: true }),
      options && options.overwrite);
  } catch (err) {
    if (callback) {
      callback(err);
      return this;
    } else {
      throw err;
    }
  }

  if (!castedDoc) {
    callback && callback(null, 0);
    return this;
  }

  return Query.base.update.call(this, castedQuery, castedDoc, options, callback);
}
```

---

### [Query#where(`[path]`, `[val]`)](#query_Query-where)

Specifies a `path` for use with chaining.

#### Parameters:

-   `[path]` &lt;[String](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String), [Object](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object)&gt;
-   `[val]` &lt;T&gt;

#### Returns:

-   &lt;[Query](#query-js)&gt; this

#### Example

```
// instead of writing:
User.find({age: {$gte: 21, $lte: 65}}, callback);

// we can instead write:
User.where('age').gte(21).lte(65);

// passing query conditions is permitted
User.find().where({ name: 'vonderful' })

// chaining
User
.where('age').gte(21).lte(65)
.where('name', /^vonderful/i)
.where('friends').slice(10)
.exec(callback)
```

---

### [Query#within()](#query_Query-within)

Defines a `$within` or `$geoWithin` argument for geo-spatial queries.

#### Returns:

-   &lt;[Query](#query-js)&gt; this

#### See:

-   [$polygon](http://docs.mongodb.org/manual/reference/operator/polygon/ "$polygon")
-   [$box](http://docs.mongodb.org/manual/reference/operator/box/ "$box")
-   [$geometry](http://docs.mongodb.org/manual/reference/operator/geometry/ "$geometry")
-   [$center](http://docs.mongodb.org/manual/reference/operator/center/ "$center")
-   [$centerSphere](http://docs.mongodb.org/manual/reference/operator/centerSphere/ "$centerSphere")

#### Example

```
query.where(path).within().box()
query.where(path).within().circle()
query.where(path).within().geometry()

query.where('loc').within({ center: [50,50], radius: 10, unique: true, spherical: true });
query.where('loc').within({ box: [[40.73, -73.9], [40.7, -73.988]] });
query.where('loc').within({ polygon: [[],[],[],[]] });

query.where('loc').within([], [], []) // polygon
query.where('loc').within([], []) // box
query.where('loc').within({ type: 'LineString', coordinates: [...] }); // geometry
```

**MUST** be used after `where()`.

#### NOTE:

As of Mongoose 3.7, `$geoWithin` is always used for queries. To change this behavior, see [Query.use$geoWithin](#query_Query-use%2524geoWithin).

#### NOTE:

In Mongoose 3.7, `within` changed from a getter to a function. If you need the old syntax, use [this](https://github.com/ebensing/mongoose-within).

---

### [Query#use$geoWithin](#query_Query-use%2524geoWithin)

Flag to opt out of using `$geoWithin`.

```
mongoose.Query.use$geoWithin = false;
```

MongoDB 2.4 deprecated the use of `$within`, replacing it with `$geoWithin`. Mongoose uses `$geoWithin` by default (which is 100% backward compatible with $within). If you are running an older version of MongoDB, set this flag to `false` so your `within()` queries continue to work.

show code

```
Query.use$geoWithin = mquery.use$geoWithin;
```

#### See:

-   [http://docs.mongodb.org/manual/reference/operator/geoWithin/](http://docs.mongodb.org/manual/reference/operator/geoWithin/)

---
  • schema/array.js

    SchemaArray#applyGetters(value, scope)

    Overrides the getters application for the population special-case

    Parameters:

    show code

    SchemaArray.prototype.applyGetters = function (value, scope) {
      if (this.caster.options && this.caster.options.ref) {
        // means the object id was populated
        return value;
      }
    
      return SchemaType.prototype.applyGetters.call(this, value, scope);
    };
    

    SchemaArray#cast(value, doc, init)

    Casts values for set().

    Parameters:

    • value <Object>
    • doc <Document> document that triggers the casting
    • init <Boolean> whether this is an initialization cast

    show code

    SchemaArray.prototype.cast = function (value, doc, init) {
      if (Array.isArray(value)) {
    
        if (!value.length && doc) {
          var indexes = doc.schema.indexedPaths();
    
          for (var i = 0, l = indexes.length; i < l; ++i) {
            var pathIndex = indexes[i][0][this.path];
            if ('2dsphere' === pathIndex || '2d' === pathIndex) {
              return;
            }
          }
        }
    
        if (!(value instanceof MongooseArray)) {
          value = new MongooseArray(value, this.path, doc);
        }
    
        if (this.caster) {
          try {
            for (var i = 0, l = value.length; i < l; i++) {
              value[i] = this.caster.cast(value[i], doc, init);
            }
          } catch (e) {
            // rethrow
            throw new CastError(e.type, value, this.path);
          }
        }
    
        return value;
      } else {
        // gh-2442: if we're loading this from the db and its not an array, mark
        // the whole array as modified.
        if (!!doc && !!init) {
          doc.markModified(this.path);
        }
        return this.cast([value], doc, init);
      }
    };
    

    SchemaArray#castForQuery($conditional, [value])

    Casts values for queries.

    Parameters:

    • $conditional <String>
    • [value] <T>

    show code

    SchemaArray.prototype.castForQuery = function ($conditional, value) {
      var handler
        , val;
    
      if (arguments.length === 2) {
        handler = this.$conditionalHandlers[$conditional];
    
        if (!handler) {
          throw new Error("Can't use " + $conditional + " with Array.");
        }
    
        val = handler.call(this, value);
    
      } else {
    
        val = $conditional;
        var proto = this.casterConstructor.prototype;
        var method = proto.castForQuery || proto.cast;
        var caster = this.caster;
    
        if (Array.isArray(val)) {
          val = val.map(function (v) {
            if (method) v = method.call(caster, v);
            return isMongooseObject(v) ?
              v.toObject({ virtuals: false }) :
              v;
          });
    
        } else if (method) {
          val = method.call(caster, val);
        }
      }
    
      return val && isMongooseObject(val) ?
        val.toObject({ virtuals: false }) :
        val;
    };
    

    SchemaArray#checkRequired(value)

    Check required

    Parameters:

    show code

    SchemaArray.prototype.checkRequired = function (value) {
      return !!(value && value.length);
    };
    

    SchemaArray(key, cast, options)

    Array SchemaType constructor

    Parameters:

    Inherits:

    show code

    function SchemaArray (key, cast, options) {
      if (cast) {
        var castOptions = {};
    
        if ('Object' === cast.constructor.name) {
          if (cast.type) {
            // support { type: Woot }
            castOptions = utils.clone(cast); // do not alter user arguments
            delete castOptions.type;
            cast = cast.type;
          } else {
            cast = Mixed;
          }
        }
    
        // support { type: 'String' }
        var name = 'string' == typeof cast
          ? cast
          : cast.name;
    
        var caster = name in Types
          ? Types[name]
          : cast;
    
        this.casterConstructor = caster;
        this.caster = new caster(null, castOptions);
        if (!(this.caster instanceof EmbeddedDoc)) {
          this.caster.path = key;
        }
      }
    
      SchemaType.call(this, key, options);
    
      var self = this
        , defaultArr
        , fn;
    
      if (this.defaultValue) {
        defaultArr = this.defaultValue;
        fn = 'function' == typeof defaultArr;
      }
    
      this.default(function(){
        var arr = fn ? defaultArr() : defaultArr || [];
        return new MongooseArray(arr, self.path, this);
      });
    };
    

  • schema/string.js

    SchemaString#cast()

    Casts to String

    show code

    ``` SchemaString.prototype.cast = function (value, doc, init) { if (SchemaType._isRef(this, value, doc, init)) {

    // wait! we may need to cast this to a document
    
    if (null == value) {
      return value;
    }
    
    // lazy load
    Document || (Document = require('./../document'));
    
    if (value instanceof Document) {
      value.$__.wasPopulated = true;
      return value;
    }
    
    // setting a populated path
    if ('string' == typeof value) {
      return value;
    } else if (Buffer.isBuffer(value) || !utils.isObject(value)) {
      throw new CastError('string', value, this.path);
    }
    
    // Handle the case where user directly sets a populated
    // path to a plain object; cast to the Model used in
    // the population query.
    var path = doc.$__fullPath(this.path);
    var owner = doc.ownerDocument ? doc.ownerDocument() : doc;
    var pop = owner.populated(path, true);
    var ret = new pop.options.model(value);
    ret.$__.wasPopulated = true;
    return ret;
    

    }

    if (value === null) {

    return value;
    

    }

    if (‘undefined’ !== typeof value) {

    // handle documents being passed
    if (value._id && 'string' == typeof value._id) {
      return value._id;
    }
    if (value.toString) {
      return value.toString();
    }
    

    }

  throw new CastError('string', value, this.path);
};
```

---

### [SchemaString#castForQuery(`$conditional`, `[val]`)](#schema_string_SchemaString-castForQuery)

Casts contents for queries.

#### Parameters:

-   `$conditional` &lt;[String](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String)&gt;
-   `[val]` &lt;T&gt;

show code

```
SchemaString.prototype.castForQuery = function ($conditional, val) {
  var handler;
  if (arguments.length === 2) {
    handler = this.$conditionalHandlers[$conditional];
    if (!handler)
      throw new Error("Can't use " + $conditional + " with String.");
    return handler.call(this, val);
  } else {
    val = $conditional;
    if (val instanceof RegExp) return val;
    return this.cast(val);
  }
};
```

---

### [SchemaString#checkRequired(`value`)](#schema_string_SchemaString-checkRequired)

Check required

#### Parameters:

-   `value` &lt;[String](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String), [null](#null), [undefined](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/undefined)&gt;

show code

```
SchemaString.prototype.checkRequired = function checkRequired (value, doc) {
  if (SchemaType._isRef(this, value, doc, true)) {
    return null != value;
  } else {
    return (value instanceof String || typeof value == 'string') && value.length;
  }
};
```

---

### [SchemaString#enum(`[args...]`)](#schema_string_SchemaString-enum)

Adds an enum validator

#### Parameters:

-   `[args...]` &lt;[String](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String), [Object](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object)&gt; enumeration values

#### Returns:

-   &lt;[SchemaType](#schematype_SchemaType)&gt; this

#### See:

-   [Customized Error Messages](#error_messages_MongooseError-messages "Customized Error Messages")

#### Example:

```
var states = 'opening open closing closed'.split(' ')
var s = new Schema({ state: { type: String, enum: states }})
var M = db.model('M', s)
var m = new M({ state: 'invalid' })
m.save(function (err) {
  console.error(String(err)) // ValidationError: `invalid` is not a valid enum value for path `state`.
  m.state = 'open'
  m.save(callback) // success
})

// or with custom error messages
var enu = {
  values: 'opening open closing closed'.split(' '),
  message: 'enum validator failed for path `{PATH}` with value `{VALUE}`'
}
var s = new Schema({ state: { type: String, enum: enu })
var M = db.model('M', s)
var m = new M({ state: 'invalid' })
m.save(function (err) {
  console.error(String(err)) // ValidationError: enum validator failed for path `state` with value `invalid`
  m.state = 'open'
  m.save(callback) // success
})
```

show code

```
SchemaString.prototype.enum = function () {
  if (this.enumValidator) {
    this.validators = this.validators.filter(function(v){
      return v[0] != this.enumValidator;
    }, this);
    this.enumValidator = false;
  }

  if (undefined === arguments[0] || false === arguments[0]) {
    return this;
  }

  var values;
  var errorMessage;

  if (utils.isObject(arguments[0])) {
    values = arguments[0].values;
    errorMessage = arguments[0].message;
  } else {
    values = arguments;
    errorMessage = errorMessages.String.enum;
  }

  for (var i = 0; i < values.length; i++) {
    if (undefined !== values[i]) {
      this.enumValues.push(this.cast(values[i]));
    }
  }

  var vals = this.enumValues;
  this.enumValidator = function (v) {
    return undefined === v || ~vals.indexOf(v);
  };
  this.validators.push([this.enumValidator, errorMessage, 'enum']);

  return this;
};
```

---

### [SchemaString#lowercase()](#schema_string_SchemaString-lowercase)

Adds a lowercase setter.

#### Returns:

-   &lt;[SchemaType](#schematype_SchemaType)&gt; this

#### Example:

```
var s = new Schema({ email: { type: String, lowercase: true }})
var M = db.model('M', s);
var m = new M({ email: 'SomeEmail@example.COM' });
console.log(m.email) // someemail@example.com
```

show code

```
SchemaString.prototype.lowercase = function () {
  return this.set(function (v, self) {
    if ('string' != typeof v) v = self.cast(v)
    if (v) return v.toLowerCase();
    return v;
  });
};
```

---

### [SchemaString#match(`regExp`, `[message]`)](#schema_string_SchemaString-match)

Sets a regexp validator.

#### Parameters:

-   `regExp` &lt;[RegExp](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/RegExp)&gt; regular expression to test against
-   `[message]` &lt;[String](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String)&gt; optional custom error message

#### Returns:

-   &lt;[SchemaType](#schematype_SchemaType)&gt; this

#### See:

-   [Customized Error Messages](#error_messages_MongooseError-messages "Customized Error Messages")

Any value that does not pass `regExp`.test(val) will fail validation.

#### Example:

```
var s = new Schema({ name: { type: String, match: /^a/ }})
var M = db.model('M', s)
var m = new M({ name: 'I am invalid' })
m.validate(function (err) {
  console.error(String(err)) // "ValidationError: Path `name` is invalid (I am invalid)."
  m.name = 'apples'
  m.validate(function (err) {
    assert.ok(err) // success
  })
})

// using a custom error message
var match = [ /\.html$/, "That file doesn't end in .html ({VALUE})" ];
var s = new Schema({ file: { type: String, match: match }})
var M = db.model('M', s);
var m = new M({ file: 'invalid' });
m.validate(function (err) {
  console.log(String(err)) // "ValidationError: That file doesn't end in .html (invalid)"
})
```

Empty strings, `undefined`, and `null` values always pass the match validator. If you require these values, enable the `required` validator also.

```
var s = new Schema({ name: { type: String, match: /^a/, required: true }})
```

show code

```
SchemaString.prototype.match = function match (regExp, message) {
  // yes, we allow multiple match validators

  var msg = message || errorMessages.String.match;

  function matchValidator(v) {
    if (!regExp) {
      return false;
    }

    return null != v && '' !== v ?
      regExp.test(v) :
      true;
  }

  this.validators.push([matchValidator, msg, 'regexp']);
  return this;
};
```

---

### [SchemaString(`key`, `options`)](#schema_string_SchemaString)

String SchemaType constructor.

#### Parameters:

-   `key` &lt;[String](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String)&gt;
-   `options` &lt;[Object](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object)&gt;

#### Inherits:

-   [SchemaType](#schematype_SchemaType)

show code

```
function SchemaString (key, options) {
  this.enumValues = [];
  this.regExp = null;
  SchemaType.call(this, key, options, 'String');
};
```

---

### [SchemaString#trim()](#schema_string_SchemaString-trim)

Adds a trim setter.

#### Returns:

-   &lt;[SchemaType](#schematype_SchemaType)&gt; this

The string value will be trimmed when set.

#### Example:

```
var s = new Schema({ name: { type: String, trim: true }})
var M = db.model('M', s)
var string = ' some name '
console.log(string.length) // 11
var m = new M({ name: string })
console.log(m.name.length) // 9
```

show code

```
SchemaString.prototype.trim = function () {
  return this.set(function (v, self) {
    if ('string' != typeof v) v = self.cast(v)
    if (v) return v.trim();
    return v;
  });
};
```

---

### [SchemaString#uppercase()](#schema_string_SchemaString-uppercase)

Adds an uppercase setter.

#### Returns:

-   &lt;[SchemaType](#schematype_SchemaType)&gt; this

#### Example:

```
var s = new Schema({ caps: { type: String, uppercase: true }})
var M = db.model('M', s);
var m = new M({ caps: 'an example' });
console.log(m.caps) // AN EXAMPLE
```

show code

```
SchemaString.prototype.uppercase = function () {
  return this.set(function (v, self) {
    if ('string' != typeof v) v = self.cast(v)
    if (v) return v.toUpperCase();
    return v;
  });
};
```

---
  • schema/documentarray.js

    DocumentArray#cast(value, document)

    Casts contents

    Parameters:

    show code

    DocumentArray.prototype.cast = function (value, doc, init, prev) {
      var selected
        , subdoc
        , i
    
      if (!Array.isArray(value)) {
        // gh-2442 mark whole array as modified if we're initializing a doc from
        // the db and the path isn't an array in the document
        if (!!doc && init) {
          doc.markModified(this.path);
        }
        return this.cast([value], doc, init, prev);
      }
    
      if (!(value instanceof MongooseDocumentArray)) {
        value = new MongooseDocumentArray(value, this.path, doc);
        if (prev && prev._handlers) {
          for (var key in prev._handlers) {
            doc.removeListener(key, prev._handlers[key]);
          }
        }
      }
    
      i = value.length;
    
      while (i--) {
        if (!(value[i] instanceof Subdocument) && value[i]) {
          if (init) {
            selected || (selected = scopePaths(this, doc.$__.selected, init));
            subdoc = new this.casterConstructor(null, value, true, selected);
            value[i] = subdoc.init(value[i]);
          } else {
            try {
              subdoc = prev.id(value[i]._id);
            } catch(e) {}
    
            if (prev && subdoc) {
              // handle resetting doc with existing id but differing data
              // doc.array = [{ doc: 'val' }]
              subdoc.set(value[i]);
            } else {
              subdoc = new this.casterConstructor(value[i], value);
            }
    
            // if set() is hooked it will have no return value
            // see gh-746
            value[i] = subdoc;
          }
        }
      }
    
      return value;
    }
    

    DocumentArray(key, schema, options)

    SubdocsArray SchemaType constructor

    Parameters:

    Inherits:

    show code

    function DocumentArray (key, schema, options) {
      // compile an embedded document for this schema
      function EmbeddedDocument () {
        Subdocument.apply(this, arguments);
      }
    
      EmbeddedDocument.prototype.__proto__ = Subdocument.prototype;
      EmbeddedDocument.prototype.$__setSchema(schema);
      EmbeddedDocument.schema = schema;
    
      // apply methods
      for (var i in schema.methods) {
        EmbeddedDocument.prototype[i] = schema.methods[i];
      }
    
      // apply statics
      for (var i in schema.statics)
        EmbeddedDocument[i] = schema.statics[i];
    
      EmbeddedDocument.options = options;
      this.schema = schema;
    
      ArrayType.call(this, key, EmbeddedDocument, options);
    
      this.schema = schema;
      var path = this.path;
      var fn = this.defaultValue;
    
      this.default(function(){
        var arr = fn.call(this);
        if (!Array.isArray(arr)) arr = [arr];
        return new MongooseDocumentArray(arr, path, this);
      });
    };
    

    DocumentArray#doValidate()

    Performs local validations first, then validations on each embedded doc

    show code

    DocumentArray.prototype.doValidate = function (array, fn, scope) {
      var self = this;
    
      SchemaType.prototype.doValidate.call(this, array, function (err) {
        if (err) return fn(err);
    
        var count = array && array.length
          , error;
    
        if (!count) return fn();
    
        // handle sparse arrays, do not use array.forEach which does not
        // iterate over sparse elements yet reports array.length including
        // them :(
    
        for (var i = 0, len = count; i < len; ++i) {
          // sidestep sparse entries
          var doc = array[i];
          if (!doc) {
            --count || fn();
            continue;
          }
    
          ;(function (i) {
            doc.validate(function (err) {
              if (err && !error) {
                // rewrite the key
                err.key = self.key + '.' + i + '.' + err.key;
                return fn(error = err);
              }
              --count || fn();
            });
          })(i);
        }
      }, scope);
    };
    

  • schema/number.js

    SchemaNumber#cast(value, doc, init)

    Casts to number

    Parameters:

    show code

    SchemaNumber.prototype.cast = function (value, doc, init) {
      if (SchemaType._isRef(this, value, doc, init)) {
        // wait! we may need to cast this to a document
    
        if (null == value) {
          return value;
        }
    
        // lazy load
        Document || (Document = require('./../document'));
    
        if (value instanceof Document) {
          value.$__.wasPopulated = true;
          return value;
        }
    
        // setting a populated path
        if ('number' == typeof value) {
          return value;
        } else if (Buffer.isBuffer(value) || !utils.isObject(value)) {
          throw new CastError('number', value, this.path);
        }
    
        // Handle the case where user directly sets a populated
        // path to a plain object; cast to the Model used in
        // the population query.
        var path = doc.$__fullPath(this.path);
        var owner = doc.ownerDocument ? doc.ownerDocument() : doc;
        var pop = owner.populated(path, true);
        var ret = new pop.options.model(value);
        ret.$__.wasPopulated = true;
        return ret;
      }
    
      var val = value && value._id
        ? value._id // documents
        : value;
    
      if (!isNaN(val)){
        if (null === val) return val;
        if ('' === val) return null;
        if ('string' == typeof val) val = Number(val);
        if (val instanceof Number) return val
        if ('number' == typeof val) return val;
        if (val.toString && !Array.isArray(val) &&
            val.toString() == Number(val)) {
          return new Number(val)
        }
      }
    
      throw new CastError('number', value, this.path);
    };
    

    SchemaNumber#castForQuery($conditional, [value])

    Casts contents for queries.

    Parameters:

    • $conditional <String>
    • [value] <T>

    show code

    SchemaNumber.prototype.castForQuery = function ($conditional, val) {
      var handler;
      if (arguments.length === 2) {
        handler = this.$conditionalHandlers[$conditional];
        if (!handler)
          throw new Error("Can't use " + $conditional + " with Number.");
        return handler.call(this, val);
      } else {
        val = this.cast($conditional);
        return val == null ? val : val
      }
    };
    

    SchemaNumber#checkRequired()

    Required validator for number

    show code

    SchemaNumber.prototype.checkRequired = function checkRequired (value, doc) {
      if (SchemaType._isRef(this, value, doc, true)) {
        return null != value;
      } else {
        return typeof value == 'number' || value instanceof Number;
      }
    };
    

    SchemaNumber#max(maximum, [message])

    Sets a maximum number validator.

    Parameters:

    • maximum <Number> number
    • [message] <String> optional custom error message

    Returns:

    See:

    Example:

    var s = new Schema({ n: { type: Number, max: 10 })
    var M = db.model('M', s)
    var m = new M({ n: 11 })
    m.save(function (err) {
      console.error(err) // validator error
      m.n = 10;
      m.save() // success
    })
    
    // custom error messages
    // We can also use the special {MAX} token which will be replaced with the invalid value
    var max = [10, 'The value of path `{PATH}` ({VALUE}) exceeds the limit ({MAX}).'];
    var schema = new Schema({ n: { type: Number, max: max })
    var M = mongoose.model('Measurement', schema);
    var s= new M({ n: 4 });
    s.validate(function (err) {
      console.log(String(err)) // ValidationError: The value of path `n` (4) exceeds the limit (10).
    })
    

    show code

    SchemaNumber.prototype.max = function (value, message) {
      if (this.maxValidator) {
        this.validators = this.validators.filter(function(v){
          return v[0] != this.maxValidator;
        }, this);
      }
    
      if (null != value) {
        var msg = message || errorMessages.Number.max;
        msg = msg.replace(/{MAX}/, value);
        this.validators.push([this.maxValidator = function(v){
          return v === null || v <= value;
        }, msg, 'max']);
      }
    
      return this;
    };
    

    SchemaNumber#min(value, [message])

    Sets a minimum number validator.

    Parameters:

    • value <Number> minimum number
    • [message] <String> optional custom error message

    Returns:

    See:

    Example:

    var s = new Schema({ n: { type: Number, min: 10 })
    var M = db.model('M', s)
    var m = new M({ n: 9 })
    m.save(function (err) {
      console.error(err) // validator error
      m.n = 10;
      m.save() // success
    })
    
    // custom error messages
    // We can also use the special {MIN} token which will be replaced with the invalid value
    var min = [10, 'The value of path `{PATH}` ({VALUE}) is beneath the limit ({MIN}).'];
    var schema = new Schema({ n: { type: Number, min: min })
    var M = mongoose.model('Measurement', schema);
    var s= new M({ n: 4 });
    s.validate(function (err) {
      console.log(String(err)) // ValidationError: The value of path `n` (4) is beneath the limit (10).
    })
    

    show code

    SchemaNumber.prototype.min = function (value, message) {
      if (this.minValidator) {
        this.validators = this.validators.filter(function (v) {
          return v[0] != this.minValidator;
        }, this);
      }
    
      if (null != value) {
        var msg = message || errorMessages.Number.min;
        msg = msg.replace(/{MIN}/, value);
        this.validators.push([this.minValidator = function (v) {
          return v === null || v >= value;
        }, msg, 'min']);
      }
    
      return this;
    };
    

    SchemaNumber(key, options)

    Number SchemaType constructor.

    Parameters:

    Inherits:

    show code

    function SchemaNumber (key, options) {
      SchemaType.call(this, key, options, 'Number');
    };
    

  • schema/date.js

    SchemaDate#cast(value)

    Casts to date

    Parameters:

    show code

    SchemaDate.prototype.cast = function (value) {
      if (value === null || value === '')
        return null;
    
      if (value instanceof Date)
        return value;
    
      var date;
    
      // support for timestamps
      if (typeof value !== 'undefined') {
        if (value instanceof Number || 'number' == typeof value
            || String(value) == Number(value)) {
          date = new Date(Number(value));
        } else if (value.toString) {
          // support for date strings
          date = new Date(value.toString());
        }
    
        if (date.toString() != 'Invalid Date') {
          return date;
        }
      }
    
      throw new CastError('date', value, this.path);
    };
    

    SchemaDate#castForQuery($conditional, [value])

    Casts contents for queries.

    Parameters:

    • $conditional <String>
    • [value] <T>

    show code

    SchemaDate.prototype.castForQuery = function ($conditional, val) {
      var handler;
    
      if (2 !== arguments.length) {
        return this.cast($conditional);
      }
    
      handler = this.$conditionalHandlers[$conditional];
    
      if (!handler) {
        throw new Error("Can't use " + $conditional + " with Date.");
      }
    
      return handler.call(this, val);
    };
    

    SchemaDate#checkRequired()

    Required validator for date

    show code

    SchemaDate.prototype.checkRequired = function (value) {
      return value instanceof Date;
    };
    

    SchemaDate#expires(when)

    Declares a TTL index (rounded to the nearest second) for Date types only.

    Parameters:

    Returns:

    This sets the expiresAfterSeconds index option available in MongoDB >= 2.1.2.
    This index type is only compatible with Date types.

    Example:

    // expire in 24 hours
    new Schema({ createdAt: { type: Date, expires: 60*60*24 }});
    

    expires utilizes the ms module from guille allowing us to use a friendlier syntax:

    Example:

    // expire in 24 hours
    new Schema({ createdAt: { type: Date, expires: '24h' }});
    
    // expire in 1.5 hours
    new Schema({ createdAt: { type: Date, expires: '1.5h' }});
    
    // expire in 7 days
    var schema = new Schema({ createdAt: Date });
    schema.path('createdAt').expires('7d');
    

    show code

    SchemaDate.prototype.expires = function (when) {
      if (!this._index || 'Object' !== this._index.constructor.name) {
        this._index = {};
      }
    
      this._index.expires = when;
      utils.expires(this._index);
      return this;
    };
    

    SchemaDate(key, options)

    Date SchemaType constructor.

    Parameters:

    Inherits:

    show code

    function SchemaDate (key, options) {
      SchemaType.call(this, key, options);
    };
    

  • schema/buffer.js

    SchemaBuffer#cast(value, doc, init)

    Casts contents

    Parameters:

    show code

    SchemaBuffer.prototype.cast = function (value, doc, init) {
      if (SchemaType._isRef(this, value, doc, init)) {
        // wait! we may need to cast this to a document
    
        if (null == value) {
          return value;
        }
    
        // lazy load
        Document || (Document = require('./../document'));
    
        if (value instanceof Document) {
          value.$__.wasPopulated = true;
          return value;
        }
    
        // setting a populated path
        if (Buffer.isBuffer(value)) {
          return value;
        } else if (!utils.isObject(value)) {
          throw new CastError('buffer', value, this.path);
        }
    
        // Handle the case where user directly sets a populated
        // path to a plain object; cast to the Model used in
        // the population query.
        var path = doc.$__fullPath(this.path);
        var owner = doc.ownerDocument ? doc.ownerDocument() : doc;
        var pop = owner.populated(path, true);
        var ret = new pop.options.model(value);
        ret.$__.wasPopulated = true;
        return ret;
      }
    
      // documents
      if (value && value._id) {
        value = value._id;
      }
    
      if (Buffer.isBuffer(value)) {
        if (!(value instanceof MongooseBuffer)) {
          value = new MongooseBuffer(value, [this.path, doc]);
        }
    
        return value;
      } else if (value instanceof Binary) {
        var ret = new MongooseBuffer(value.value(true), [this.path, doc]);
        if (typeof value.sub_type !== 'number') {
          throw new CastError('buffer', value, this.path);
        }
        ret._subtype = value.sub_type;
        return ret;
      }
    
      if (null === value) return value;
    
      var type = typeof value;
      if ('string' == type || 'number' == type || Array.isArray(value)) {
        if (type === 'number') {
          value = [value];
        }
        var ret = new MongooseBuffer(value, [this.path, doc]);
        return ret;
      }
    
      throw new CastError('buffer', value, this.path);
    };
    

    SchemaBuffer#castForQuery($conditional, [value])

    Casts contents for queries.

    Parameters:

    • $conditional <String>
    • [value] <T>

    show code

    SchemaBuffer.prototype.castForQuery = function ($conditional, val) {
      var handler;
      if (arguments.length === 2) {
        handler = this.$conditionalHandlers[$conditional];
        if (!handler)
          throw new Error("Can't use " + $conditional + " with Buffer.");
        return handler.call(this, val);
      } else {
        val = $conditional;
        return this.cast(val).toObject();
      }
    };
    

    SchemaBuffer#checkRequired()

    Check required

    show code

    SchemaBuffer.prototype.checkRequired = function (value, doc) {
      if (SchemaType._isRef(this, value, doc, true)) {
        return null != value;
      } else {
        return !!(value && value.length);
      }
    };
    

    SchemaBuffer(key, cast)

    Buffer SchemaType constructor

    Parameters:

    Inherits:

    show code

    function SchemaBuffer (key, options) {
      SchemaType.call(this, key, options, 'Buffer');
    };
    

  • schema/boolean.js

    SchemaBoolean#cast(value)

    Casts to boolean

    Parameters:

    show code

    SchemaBoolean.prototype.cast = function (value) {
      if (null === value) return value;
      if ('0' === value) return false;
      if ('true' === value) return true;
      if ('false' === value) return false;
      return !! value;
    }
    

    SchemaBoolean#castForQuery($conditional, val)

    Casts contents for queries.

    Parameters:

    show code

    SchemaBoolean.prototype.castForQuery = function ($conditional, val) {
      var handler;
      if (2 === arguments.length) {
        handler = SchemaBoolean.$conditionalHandlers[$conditional];
    
        if (handler) {
          return handler.call(this, val);
        }
    
        return this.cast(val);
      }
    
      return this.cast($conditional);
    };
    

    SchemaBoolean#checkRequired()

    Required validator

    show code

    SchemaBoolean.prototype.checkRequired = function (value) {
      return value === true || value === false;
    };
    

    SchemaBoolean(path, options)

    Boolean SchemaType constructor.

    Parameters:

    Inherits:

    show code

    function SchemaBoolean (path, options) {
      SchemaType.call(this, path, options);
    };
    

  • schema/objectid.js

    ObjectId#auto(turnOn)

    Adds an auto-generated ObjectId default if turnOn is true.

    Parameters:

    • turnOn <Boolean> auto generated ObjectId defaults

    Returns:

    show code

    ObjectId.prototype.auto = function (turnOn) {
      if (turnOn) {
        this.default(defaultId);
        this.set(resetId)
      }
    
      return this;
    };
    

    ObjectId#cast(value, doc, init)

    Casts to ObjectId

    Parameters:

    show code

    ObjectId.prototype.cast = function (value, doc, init) {
      if (SchemaType._isRef(this, value, doc, init)) {
        // wait! we may need to cast this to a document
    
        if (null == value) {
          return value;
        }
    
        // lazy load
        Document || (Document = require('./../document'));
    
        if (value instanceof Document) {
          value.$__.wasPopulated = true;
          return value;
        }
    
        // setting a populated path
        if (value instanceof oid) {
          return value;
        } else if (Buffer.isBuffer(value) || !utils.isObject(value)) {
          throw new CastError('ObjectId', value, this.path);
        }
    
        // Handle the case where user directly sets a populated
        // path to a plain object; cast to the Model used in
        // the population query.
        var path = doc.$__fullPath(this.path);
        var owner = doc.ownerDocument ? doc.ownerDocument() : doc;
        var pop = owner.populated(path, true);
        var ret = new pop.options.model(value);
        ret.$__.wasPopulated = true;
        return ret;
      }
    
      // If null or undefined
      if (value == null) return value;
    
      if (value instanceof oid)
        return value;
    
      if (value._id && value._id instanceof oid)
        return value._id;
    
      if (value.toString) {
        try {
          return oid.createFromHexString(value.toString());
        } catch (err) {
          throw new CastError('ObjectId', value, this.path);
        }
      }
    
      throw new CastError('ObjectId', value, this.path);
    };
    

    ObjectId#castForQuery($conditional, [val])

    Casts contents for queries.

    Parameters:

    • $conditional <String>
    • [val] <T>

    show code

    ObjectId.prototype.castForQuery = function ($conditional, val) {
      var handler;
      if (arguments.length === 2) {
        handler = this.$conditionalHandlers[$conditional];
        if (!handler)
          throw new Error("Can't use " + $conditional + " with ObjectId.");
        return handler.call(this, val);
      } else {
        return this.cast($conditional);
      }
    };
    

    ObjectId#checkRequired()

    Check required

    show code

    ObjectId.prototype.checkRequired = function checkRequired (value, doc) {
      if (SchemaType._isRef(this, value, doc, true)) {
        return null != value;
      } else {
        return value instanceof oid;
      }
    };
    

    ObjectId(key, options)

    ObjectId SchemaType constructor.

    Parameters:

    Inherits:

    show code

    function ObjectId (key, options) {
      SchemaType.call(this, key, options, 'ObjectID');
    };
    

  • schema/mixed.js

    Mixed#cast(value)

    Casts val for Mixed.

    Parameters:

    this is a no-op

    show code

    Mixed.prototype.cast = function (val) {
      return val;
    };
    

    Mixed#castForQuery($cond, [val])

    Casts contents for queries.

    Parameters:

    show code

    Mixed.prototype.castForQuery = function ($cond, val) {
      if (arguments.length === 2) return val;
      return $cond;
    };
    

    Mixed#checkRequired()

    Required validator

    show code

    Mixed.prototype.checkRequired = function (val) {
      return (val !== undefined) && (val !== null);
    };
    

    Mixed(path, options)

    Mixed SchemaType constructor.

    Parameters:

    Inherits:

    show code

    function Mixed (path, options) {
      if (options && options.default) {
        var def = options.default;
        if (Array.isArray(def) && 0 === def.length) {
          // make sure empty array defaults are handled
          options.default = Array;
        } else if (!options.shared &&
                   utils.isObject(def) &&
                   0 === Object.keys(def).length) {
          // prevent odd "shared" objects between documents
          options.default = function () {
            return {}
          }
        }
      }
    
      SchemaType.call(this, path, options);
    };
    

  • aggregate.js

    Aggregate([ops])

    Aggregate constructor used for building aggregation pipelines.

    Parameters:

    • [ops] <Object, Array> aggregation operator(s) or operator array

    See:

    Example:

    new Aggregate();
    new Aggregate({ $project: { a: 1, b: 1 } });
    new Aggregate({ $project: { a: 1, b: 1 } }, { $skip: 5 });
    new Aggregate([{ $project: { a: 1, b: 1 } }, { $skip: 5 }]);
    

    Returned when calling Model.aggregate().

    Example:

    Model
    .aggregate({ $match: { age: { $gte: 21 }}})
    .unwind('tags')
    .exec(callback)
    

    Note:

    • The documents returned are plain javascript objects, not mongoose documents (since any shape of document can be returned).
    • Requires MongoDB >= 2.1

    show code

    function Aggregate () {
      this._pipeline = [];
      this._model = undefined;
      this.options = undefined;
    
      if (1 === arguments.length && util.isArray(arguments[0])) {
        this.append.apply(this, arguments[0]);
      } else {
        this.append.apply(this, arguments);
      }
    }
    

    Aggregate#allowDiskUse(value, [tags])

    Sets the allowDiskUse option for the aggregation query (ignored for < 2.6.0)

    Parameters:

    • value <Boolean> Should tell server it can use hard drive to store data during aggregation.
    • [tags] <Array> optional tags for this query

    See:

    Example:

    Model.aggregate(..).allowDiskUse(true).exec(callback)
    

    show code

    Aggregate.prototype.allowDiskUse = function(value) {
      if (!this.options) this.options = {};
      this.options.allowDiskUse = value;
      return this;
    };
    

    Aggregate#append(ops)

    Appends new operators to this aggregate pipeline

    Parameters:

    • ops <Object> operator(s) to append

    Returns:

    Examples:

    aggregate.append({ $project: { field: 1 }}, { $limit: 2 });
    
    // or pass an array
    var pipeline = [{ $match: { daw: 'Logic Audio X' }} ];
    aggregate.append(pipeline);
    

    show code

    Aggregate.prototype.append = function () {
      var args = (1 === arguments.length && util.isArray(arguments[0]))
          ? arguments[0]
          : utils.args(arguments);
    
      if (!args.every(isOperator)) {
        throw new Error("Arguments must be aggregate pipeline operators");
      }
    
      this._pipeline = this._pipeline.concat(args);
    
      return this;
    }
    

    Aggregate#bind(model)

    Binds this aggregate to a model.

    Parameters:

    • model <Model> the model to which the aggregate is to be bound

    Returns:

    show code

    Aggregate.prototype.bind = function (model) {
      this._model = model;
      return this;
    }
    

    Aggregate#cursor(options)

    Sets the cursor option option for the aggregation query (ignored for < 2.6.0)

    Parameters:

    • options <Object> set the cursor batch size

    See:

    Example:

    Model.aggregate(..).cursor({ batchSize: 1000 }).exec(callback)
    

    show code

    Aggregate.prototype.cursor = function(options) {
      if (!this.options) this.options = {};
      this.options.cursor = options;
      return this;
    };
    

    Aggregate#exec([callback])

    Executes the aggregate pipeline on the currently bound Model.

    Parameters:

    Returns:

    See:

    Example:

    aggregate.exec(callback);
    
    // Because a promise is returned, the `callback` is optional.
    var promise = aggregate.exec();
    promise.then(..);
    

    show code

    Aggregate.prototype.exec = function (callback) {
      var promise = new Promise();
    
      if (callback) {
        promise.addBack(callback);
      }
    
      if (!this._pipeline.length) {
        promise.error(new Error("Aggregate has empty pipeline"));
        return promise;
      }
    
      if (!this._model) {
        promise.error(new Error("Aggregate not bound to any Model"));
        return promise;
      }
    
      this._model
        .collection
        .aggregate(this._pipeline, this.options || {}, promise.resolve.bind(promise));
    
      return promise;
    }
    

    Aggregate#group(arg)

    Appends a new custom $group operator to this aggregate pipeline.

    Parameters:

    • arg <Object> $group operator contents

    Returns:

    See:

    Examples:

    aggregate.group({ _id: "$department" });
    

    isOperator(obj)

    Checks whether an object is likely a pipeline operator

    Parameters:

    Returns:

    show code

    function isOperator (obj) {
      var k;
    
      if ('object' !== typeof obj) {
        return false;
      }
    
      k = Object.keys(obj);
    
      return 1 === k.length && k.some(function (key) {
        return '$' === key[0];
      });
    }
    

    Aggregate#limit(num)

    Appends a new $limit operator to this aggregate pipeline.

    Parameters:

    • num <Number> maximum number of records to pass to the next stage

    Returns:

    See:

    Examples:

    aggregate.limit(10);
    

    Aggregate#match(arg)

    Appends a new custom $match operator to this aggregate pipeline.

    Parameters:

    • arg <Object> $match operator contents

    Returns:

    See:

    Examples:

    aggregate.match({ department: { $in: [ "sales", "engineering" } } });
    

    Aggregate#near(parameters)

    Appends a new $geoNear operator to this aggregate pipeline.

    Parameters:

    Returns:

    See:

    NOTE:

    MUST be used as the first operator in the pipeline.

    Examples:

    aggregate.near({
      near: [40.724, -73.997],
      distanceField: "dist.calculated", // required
      maxDistance: 0.008,
      query: { type: "public" },
      includeLocs: "dist.location",
      uniqueDocs: true,
      num: 5
    });
    

    Aggregate#project(arg)

    Appends a new $project operator to this aggregate pipeline.

    Parameters:

    Returns:

    See:

    Mongoose query selection syntax is also supported.

    Examples:

    // include a, include b, exclude _id
    aggregate.project("a b -_id");
    
    // or you may use object notation, useful when
    // you have keys already prefixed with a "-"
    aggregate.project({a: 1, b: 1, _id: 0});
    
    // reshaping documents
    aggregate.project({
        newField: '$b.nested'
      , plusTen: { $add: ['$val', 10]}
      , sub: {
           name: '$a'
        }
    })
    
    // etc
    aggregate.project({ salary_k: { $divide: [ "$salary", 1000 ] } });
    

    show code

    Aggregate.prototype.project = function (arg) {
      var fields = {};
    
      if ('object' === typeof arg && !util.isArray(arg)) {
        Object.keys(arg).forEach(function (field) {
          fields[field] = arg[field];
        });
      } else if (1 === arguments.length && 'string' === typeof arg) {
        arg.split(/\s+/).forEach(function (field) {
          if (!field) return;
          var include = '-' == field[0] ? 0 : 1;
          if (include === 0) field = field.substring(1);
          fields[field] = include;
        });
      } else {
        throw new Error("Invalid project() argument. Must be string or object");
      }
    
      return this.append({ $project: fields });
    }
    

    Aggregate#read(pref, [tags])

    Sets the readPreference option for the aggregation query.

    Parameters:

    • pref <String> one of the listed preference options or their aliases
    • [tags] <Array> optional tags for this query

    See:

    Example:

    Model.aggregate(..).read('primaryPreferred').exec(callback)
    

    show code

    Aggregate.prototype.read = function (pref) {
      if (!this.options) this.options = {};
      read.apply(this, arguments);
      return this;
    };
    

    Aggregate#skip(num)

    Appends a new $skip operator to this aggregate pipeline.

    Parameters:

    • num <Number> number of records to skip before next stage

    Returns:

    See:

    Examples:

    aggregate.skip(10);
    

    Aggregate#sort(arg)

    Appends a new $sort operator to this aggregate pipeline.

    Parameters:

    Returns:

    See:

    If an object is passed, values allowed are asc, desc, ascending, descending, 1, and -1.

    If a string is passed, it must be a space delimited list of path names. The sort order of each path is ascending unless the path name is prefixed with - which will be treated as descending.

    Examples:

    // these are equivalent
    aggregate.sort({ field: 'asc', test: -1 });
    aggregate.sort('field -test');
    

    show code

    Aggregate.prototype.sort = function (arg) {
      // TODO refactor to reuse the query builder logic
    
      var sort = {};
    
      if ('Object' === arg.constructor.name) {
        var desc = ['desc', 'descending', -1];
        Object.keys(arg).forEach(function (field) {
          sort[field] = desc.indexOf(arg[field]) === -1 ? 1 : -1;
        });
      } else if (1 === arguments.length && 'string' == typeof arg) {
        arg.split(/\s+/).forEach(function (field) {
          if (!field) return;
          var ascend = '-' == field[0] ? -1 : 1;
          if (ascend === -1) field = field.substring(1);
          sort[field] = ascend;
        });
      } else {
        throw new TypeError('Invalid sort() argument. Must be a string or object.');
      }
    
      return this.append({ $sort: sort });
    }
    

    Aggregate#unwind(fields)

    Appends new custom $unwind operator(s) to this aggregate pipeline.

    Parameters:

    • fields <String> the field(s) to unwind

    Returns:

    See:

    Examples:

    aggregate.unwind("tags");
    aggregate.unwind("a", "b", "c");
    

    show code

    Aggregate.prototype.unwind = function () {
      var args = utils.args(arguments);
    
      return this.append.apply(this, args.map(function (arg) {
        return { $unwind: '$' + arg };
      }));
    };
    

  • schematype.js

    SchemaType#applyGetters(value, scope)

    Applies getters to a value

    Parameters:

    show code

    SchemaType.prototype.applyGetters = function (value, scope) {
      if (SchemaType._isRef(this, value, scope, true)) return value;
    
      var v = value
        , getters = this.getters
        , len = getters.length;
    
      if (!len) {
        return v;
      }
    
      while (len--) {
        v = getters[len].call(scope, v, this);
      }
    
      return v;
    };
    

    SchemaType#applySetters(value, scope, init)

    Applies setters

    Parameters:

    show code

    SchemaType.prototype.applySetters = function (value, scope, init, priorVal) {
      if (SchemaType._isRef(this, value, scope, init)) {
        return init
          ? value
          : this.cast(value, scope, init, priorVal);
      }
    
      var v = value
        , setters = this.setters
        , len = setters.length
    
      if (!len) {
        if (null === v || undefined === v) return v;
        return this.cast(v, scope, init, priorVal)
      }
    
      while (len--) {
        v = setters[len].call(scope, v, this);
      }
    
      if (null === v || undefined === v) return v;
    
      // do not cast until all setters are applied #665
      v = this.cast(v, scope, init, priorVal);
    
      return v;
    };
    

    SchemaType#default(val)

    Sets a default value for this SchemaType.

    Parameters:

    Returns:

    Example:

    var schema = new Schema({ n: { type: Number, default: 10 })
    var M = db.model('M', schema)
    var m = new M;
    console.log(m.n) // 10
    

    Defaults can be either functions which return the value to use as the default or the literal value itself. Either way, the value will be cast based on its schema type before being set during document creation.

    Example:

    // values are cast:
    var schema = new Schema({ aNumber: Number, default: "4.815162342" })
    var M = db.model('M', schema)
    var m = new M;
    console.log(m.aNumber) // 4.815162342
    
    // default unique objects for Mixed types:
    var schema = new Schema({ mixed: Schema.Types.Mixed });
    schema.path('mixed').default(function () {
      return {};
    });
    
    // if we don't use a function to return object literals for Mixed defaults,
    // each document will receive a reference to the same object literal creating
    // a "shared" object instance:
    var schema = new Schema({ mixed: Schema.Types.Mixed });
    schema.path('mixed').default({});
    var M = db.model('M', schema);
    var m1 = new M;
    m1.mixed.added = 1;
    console.log(m1.mixed); // { added: 1 }
    var m2 = new M;
    console.log(m2.mixed); // { added: 1 }
    

    show code

    SchemaType.prototype.default = function (val) {
      if (1 === arguments.length) {
        this.defaultValue = typeof val === 'function'
          ? val
          : this.cast(val);
        return this;
      } else if (arguments.length > 1) {
        this.defaultValue = utils.args(arguments);
      }
      return this.defaultValue;
    };
    

    SchemaType#doValidate(value, callback, scope)

    Performs a validation of value using the validators declared for this SchemaType.

    Parameters:

    show code

    SchemaType.prototype.doValidate = function (value, fn, scope) {
      var err = false
        , path = this.path
        , count = this.validators.length;
    
      if (!count) return fn(null);
    
      function validate (ok, message, type, val) {
        if (err) return;
        if (ok === undefined || ok) {
          --count || fn(null);
        } else {
          fn(err = new ValidatorError(path, message, type, val));
        }
      }
    
      this.validators.forEach(function (v) {
        var validator = v[0]
          , message = v[1]
          , type = v[2];
    
        if (validator instanceof RegExp) {
          validate(validator.test(value), message, type, value);
        } else if ('function' === typeof validator) {
          if (2 === validator.length) {
            validator.call(scope, value, function (ok) {
              validate(ok, message, type, value);
            });
          } else {
            validate(validator.call(scope, value), message, type, value);
          }
        }
      });
    };
    

    SchemaType#get(fn)

    Adds a getter to this schematype.

    Parameters:

    Returns:

    Example:

    function dob (val) {
      if (!val) return val;
      return (val.getMonth() + 1) + "/" + val.getDate() + "/" + val.getFullYear();
    }
    
    // defining within the schema
    var s = new Schema({ born: { type: Date, get: dob })
    
    // or by retreiving its SchemaType
    var s = new Schema({ born: Date })
    s.path('born').get(dob)
    

    Getters allow you to transform the representation of the data as it travels from the raw mongodb document to the value that you see.

    Suppose you are storing credit card numbers and you want to hide everything except the last 4 digits to the mongoose user. You can do so by defining a getter in the following way:

    function obfuscate (cc) {
      return '****-****-****-' + cc.slice(cc.length-4, cc.length);
    }
    
    var AccountSchema = new Schema({
      creditCardNumber: { type: String, get: obfuscate }
    });
    
    var Account = db.model('Account', AccountSchema);
    
    Account.findById(id, function (err, found) {
      console.log(found.creditCardNumber); // '****-****-****-1234'
    });
    

    Getters are also passed a second argument, the schematype on which the getter was defined. This allows for tailored behavior based on options passed in the schema.

    function inspector (val, schematype) {
      if (schematype.options.required) {
        return schematype.path + ' is required';
      } else {
        return schematype.path + ' is not';
      }
    }
    
    var VirusSchema = new Schema({
      name: { type: String, required: true, get: inspector },
      taxonomy: { type: String, get: inspector }
    })
    
    var Virus = db.model('Virus', VirusSchema);
    
    Virus.findById(id, function (err, virus) {
      console.log(virus.name);     // name is required
      console.log(virus.taxonomy); // taxonomy is not
    })
    

    show code

    SchemaType.prototype.get = function (fn) {
      if ('function' != typeof fn)
        throw new TypeError('A getter must be a function.');
      this.getters.push(fn);
      return this;
    };
    

    SchemaType#getDefault(scope, init)

    Gets the default value

    Parameters:

    • scope <Object> the scope which callback are executed
    • init <Boolean>

    show code

    SchemaType.prototype.getDefault = function (scope, init) {
      var ret = 'function' === typeof this.defaultValue
        ? this.defaultValue.call(scope)
        : this.defaultValue;
    
      if (null !== ret && undefined !== ret) {
        return this.cast(ret, scope, init);
      } else {
        return ret;
      }
    };
    

    SchemaType#index(options)

    Declares the index options for this schematype.

    Parameters:

    Returns:

    Example:

    var s = new Schema({ name: { type: String, index: true })
    var s = new Schema({ loc: { type: [Number], index: 'hashed' })
    var s = new Schema({ loc: { type: [Number], index: '2d', sparse: true })
    var s = new Schema({ loc: { type: [Number], index: { type: '2dsphere', sparse: true }})
    var s = new Schema({ date: { type: Date, index: { unique: true, expires: '1d' }})
    Schema.path('my.path').index(true);
    Schema.path('my.date').index({ expires: 60 });
    Schema.path('my.path').index({ unique: true, sparse: true });
    

    NOTE:

    Indexes are created in the background by default. Specify background: false to override.

    Direction doesn’t matter for single key indexes

    show code

    SchemaType.prototype.index = function (options) {
      this._index = options;
      utils.expires(this._index);
      return this;
    };
    

    SchemaType#required(required, [message])

    Adds a required validator to this schematype.

    Parameters:

    • required <Boolean> enable/disable the validator
    • [message] <String> optional custom error message

    Returns:

    See:

    Example:

    var s = new Schema({ born: { type: Date, required: true })
    
    // or with custom error message
    
    var s = new Schema({ born: { type: Date, required: '{PATH} is required!' })
    
    // or through the path API
    
    Schema.path('name').required(true);
    
    // with custom error messaging
    
    Schema.path('name').required(true, 'grrr :( ');
    

    show code

    SchemaType.prototype.required = function (required, message) {
      if (false === required) {
        this.validators = this.validators.filter(function (v) {
          return v[0] != this.requiredValidator;
        }, this);
    
        this.isRequired = false;
        return this;
      }
    
      var self = this;
      this.isRequired = true;
    
      this.requiredValidator = function (v) {
        // in here, `this` refers to the validating document.
        // no validation when this path wasn't selected in the query.
        if ('isSelected' in this &&
            !this.isSelected(self.path) &&
            !this.isModified(self.path)) return true;
        return self.checkRequired(v, this);
      }
    
      if ('string' == typeof required) {
        message = required;
        required = undefined;
      }
    
      var msg = message || errorMessages.general.required;
      this.validators.push([this.requiredValidator, msg, 'required']);
    
      return this;
    };
    

    SchemaType(path, [options], [instance])

    SchemaType constructor

    Parameters:

    show code

    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] && 'function' == typeof this[i]) {
          // { unique: true, index: true }
          if ('index' == i && this._index) continue;
    
          var opts = Array.isArray(options[i])
            ? options[i]
            : [options[i]];
    
          this[i].apply(this, opts);
        }
      }
    };
    

    SchemaType#select(val)

    Sets default select() behavior for this path.

    Parameters:

    Returns:

    Set to 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.

    Example:

    T = db.model('T', new Schema({ x: { type: String, select: true }}));
    T.find(..); // field x will always be selected ..
    // .. unless overridden;
    T.find().select('-x').exec(callback);
    

    show code

    SchemaType.prototype.select = function select (val) {
      this.selected = !! val;
      return this;
    }
    

    SchemaType#set(fn)

    Adds a setter to this schematype.

    Parameters:

    Returns:

    Example:

    function capitalize (val) {
      if ('string' != typeof val) val = '';
      return val.charAt(0).toUpperCase() + val.substring(1);
    }
    
    // defining within the schema
    var s = new Schema({ name: { type: String, set: capitalize }})
    
    // or by retreiving its SchemaType
    var s = new Schema({ name: String })
    s.path('name').set(capitalize)
    

    Setters allow you to transform the data before it gets to the raw mongodb document and is set as a value on an actual key.

    Suppose you are implementing user registration for a website. Users provide an email and password, which gets saved to mongodb. The email is a string that you will want to normalize to lower case, in order to avoid one email having more than one account — e.g., otherwise, avenue@q.com can be registered for 2 accounts via avenue@q.com and AvEnUe@Q.CoM.

    You can set up email lower case normalization easily via a Mongoose setter.

    function toLower (v) {
      return v.toLowerCase();
    }
    
    var UserSchema = new Schema({
      email: { type: String, set: toLower }
    })
    
    var User = db.model('User', UserSchema)
    
    var user = new User({email: 'AVENUE@Q.COM'})
    console.log(user.email); // 'avenue@q.com'
    
    // or
    var user = new User
    user.email = 'Avenue@Q.com'
    console.log(user.email) // 'avenue@q.com'
    

    As you can see above, setters allow you to transform the data before it gets to the raw mongodb document and is set as a value on an actual key.

    NOTE: we could have also just used the built-in lowercase: true SchemaType option instead of defining our own function.

    new Schema({ email: { type: String, lowercase: true }})
    

    Setters are also passed a second argument, the schematype on which the setter was defined. This allows for tailored behavior based on options passed in the schema.

    function inspector (val, schematype) {
      if (schematype.options.required) {
        return schematype.path + ' is required';
      } else {
        return val;
      }
    }
    
    var VirusSchema = new Schema({
      name: { type: String, required: true, set: inspector },
      taxonomy: { type: String, set: inspector }
    })
    
    var Virus = db.model('Virus', VirusSchema);
    var v = new Virus({ name: 'Parvoviridae', taxonomy: 'Parvovirinae' });
    
    console.log(v.name);     // name is required
    console.log(v.taxonomy); // Parvovirinae
    

    show code

    SchemaType.prototype.set = function (fn) {
      if ('function' != typeof fn)
        throw new TypeError('A setter must be a function.');
      this.setters.push(fn);
      return this;
    };
    

    SchemaType#sparse(bool)

    Declares a sparse index.

    Parameters:

    Returns:

    Example:

    var s = new Schema({ name: { type: String, sparse: true })
    Schema.path('name').index({ sparse: true });
    

    show code

    SchemaType.prototype.sparse = function (bool) {
      if (null == this._index || 'boolean' == typeof this._index) {
        this._index = {};
      } else if ('string' == typeof this._index) {
        this._index = { type: this._index };
      }
    
      this._index.sparse = bool;
      return this;
    };
    

    SchemaType#unique(bool)

    Declares an unique index.

    Parameters:

    Returns:

    Example:

    var s = new Schema({ name: { type: String, unique: true })
    Schema.path('name').index({ unique: true });
    

    NOTE: violating the constraint returns an E11000 error from MongoDB when saving, not a Mongoose validation error.

    show code

    SchemaType.prototype.unique = function (bool) {
      if (null == this._index || 'boolean' == typeof this._index) {
        this._index = {};
      } else if ('string' == typeof this._index) {
        this._index = { type: this._index };
      }
    
      this._index.unique = bool;
      return this;
    };
    

    SchemaType#validate(obj, [errorMsg])

    Adds validator(s) for this document path.

    Parameters:

    Returns:

    Validators always receive the value to validate as their first argument and must return Boolean. Returning false means validation failed.

    The error message argument is optional. If not passed, the default generic error message template will be used.

    Examples:

    // make sure every value is equal to "something"
    function validator (val) {
      return val == 'something';
    }
    new Schema({ name: { type: String, validate: validator }});
    
    // with a custom error message
    
    var custom = [validator, 'Uh oh, {PATH} does not equal "something".']
    new Schema({ name: { type: String, validate: custom }});
    
    // adding many validators at a time
    
    var many = [
        { validator: validator, msg: 'uh oh' }
      , { validator: anotherValidator, msg: 'failed' }
    ]
    new Schema({ name: { type: String, validate: many }});
    
    // or utilizing SchemaType methods directly:
    
    var schema = new Schema({ name: 'string' });
    schema.path('name').validate(validator, 'validation of `{PATH}` failed with value `{VALUE}`');
    

    Error message templates:

    From the examples above, you may have noticed that error messages support baseic templating. There are a few other template keywords besides {PATH} and {VALUE} too. To find out more, details are available here

    Asynchronous validation:

    Passing a validator function that receives two arguments tells mongoose that the validator is an asynchronous validator. The first argument passed to the validator function is the value being validated. The second argument is a callback function that must called when you finish validating the value and passed either true or false to communicate either success or failure respectively.

    schema.path('name').validate(function (value, respond) {
      doStuff(value, function () {
        ...
        respond(false); // validation failed
      })
     }, '{PATH} failed validation.');
    

    You might use asynchronous validators to retreive other documents from the database to validate against or to meet other I/O bound validation needs.

    Validation occurs pre('save') or whenever you manually execute document#validate.

    If validation fails during pre('save') and no callback was passed to receive the error, an error event will be emitted on your Models associated db connection, passing the validation error object along.

    var conn = mongoose.createConnection(..);
    conn.on('error', handleError);
    
    var Product = conn.model('Product', yourSchema);
    var dvd = new Product(..);
    dvd.save(); // emits error on the `conn` above
    

    If you desire handling these errors at the Model level, attach an error listener to your Model and the event will instead be emitted there.

    // registering an error listener on the Model lets us handle errors more locally
    Product.on('error', handleError);
    

    show code

    SchemaType.prototype.validate = function (obj, message) {
      if ('function' == typeof obj || obj && 'RegExp' === obj.constructor.name) {
        if (!message) message = errorMessages.general.default;
        this.validators.push([obj, message, 'user defined']);
        return this;
      }
    
      var i = arguments.length
        , arg
    
      while (i--) {
        arg = arguments[i];
        if (!(arg && 'Object' == arg.constructor.name)) {
          var msg = 'Invalid validator. Received (' + typeof arg + ') '
            + arg
            + '. See http://mongoosejs.com/docs/api.html#schematype_SchemaType-validate';
    
          throw new Error(msg);
        }
        this.validate(arg.validator, arg.msg);
      }
    
      return this;
    };
    

    SchemaType._isRef(self, value, doc, init)

    Determines if value is a valid Reference.

    show code

    SchemaType._isRef = function (self, value, doc, init) {
      // fast path
      var ref = init && self.options && self.options.ref;
    
      if (!ref && doc && doc.$__fullPath) {
        // checks for
        // - this populated with adhoc model and no ref was set in schema OR
        // - setting / pushing values after population
        var path = doc.$__fullPath(self.path);
        var owner = doc.ownerDocument ? doc.ownerDocument() : doc;
        ref = owner.populated(path);
      }
    
      if (ref) {
        if (null == value) return true;
        if (!Buffer.isBuffer(value) &&  // buffers are objects too
            'Binary' != value._bsontype // raw binary value from the db
            && utils.isObject(value)    // might have deselected _id in population query
           ) {
          return true;
        }
      }
    
      return false;
    };
    

    Parameters:

    Returns:


  • promise.js

    Promise#addBack(listener)

    Adds a single function as a listener to both err and complete.

    Parameters:

    Returns:

    It will be executed with traditional node.js argument position when the promise is resolved.

    promise.addBack(function (err, args...) {
      if (err) return handleError(err);
      console.log('success');
    })
    

    Alias of mpromise#onResolve.

    Deprecated. Use onResolve instead.


    Promise#addCallback(listener)

    Adds a listener to the complete (success) event.

    Parameters:

    Returns:

    Alias of mpromise#onFulfill.

    Deprecated. Use onFulfill instead.


    Promise#addErrback(listener)

    Adds a listener to the err (rejected) event.

    Parameters:

    Returns:

    Alias of mpromise#onReject.

    Deprecated. Use onReject instead.


    Promise#complete(args)

    Fulfills this promise with passed arguments.

    Parameters:

    • args <T>

    Alias of mpromise#fulfill.

    Deprecated. Use fulfill instead.


    Promise#end()

    Signifies that this promise was the last in a chain of then()s: if a handler passed to the call to then which produced this promise throws, the exception will go uncaught.

    See:

    Example:

    var p = new Promise;
    p.then(function(){ throw new Error('shucks') });
    setTimeout(function () {
      p.fulfill();
      // error was caught and swallowed by the promise returned from
      // p.then(). we either have to always register handlers on
      // the returned promises or we can do the following...
    }, 10);
    
    // this time we use .end() which prevents catching thrown errors
    var p = new Promise;
    var p2 = p.then(function(){ throw new Error('shucks') }).end(); // &lt;--
    setTimeout(function () {
      p.fulfill(); // throws "shucks"
    }, 10);
    

    Promise#error(err)

    Rejects this promise with err.

    Parameters:

    Returns:

    If the promise has already been fulfilled or rejected, not action is taken.

    Differs from #reject by first casting err to an Error if it is not instanceof Error.

    show code

    Promise.prototype.error = function (err) {
      if (!(err instanceof Error)) {
        if (err instanceof Object) {
          err = util.inspect(err);
        }
        err = new Error(err);
      }
      return this.reject(err);
    }
    

    function Object() { [native code] }#fulfill(args)%20%7B%20%5Bnative%20code%5D%20%7D-fulfill)

    Fulfills this promise with passed arguments.

    Parameters:

    • args <T>

    See:


    function Object() { [native code] }#fulfill(args)%20%7B%20%5Bnative%20code%5D%20%7D-fulfill)

    Fulfills this promise with passed arguments.

    Parameters:

    • args <T>

    See:


    Promise#on(event, listener)

    Adds listener to the event.

    Parameters:

    Returns:

    See:

    If event is either the success or failure event and the event has already been emitted, thelistener is called immediately and passed the results of the original emitted event.


    Promise(fn)

    Promise constructor.

    Parameters:

    • fn <Function> a function which will be called when the promise is resolved that accepts `fn(err, …){}` as signature

    Inherits:

    Events:

    • err: Emits when the promise is rejected

    • complete: Emits when the promise is fulfilled

    Promises are returned from executed queries. Example:

    var query = Candy.find({ bar: true });
    var promise = query.exec();
    

    show code

    function Promise (fn) {
      MPromise.call(this, fn);
    }
    

    Promise#reject(reason)

    Rejects this promise with reason.

    Parameters:

    Returns:

    See:

    If the promise has already been fulfilled or rejected, not action is taken.


    Promise#resolve([err], [val])

    Resolves this promise to a rejected state if err is passed or a fulfilled state if no err is passed.

    Parameters:

    • [err] <Error> error or null
    • [val] <Object> value to fulfill the promise with

    If the promise has already been fulfilled or rejected, not action is taken.

    err will be cast to an Error if not already instanceof Error.

    NOTE: overrides mpromise#resolve to provide error casting.

    show code

    Promise.prototype.resolve = function (err) {
      if (err) return this.error(err);
      return this.fulfill.apply(this, Array.prototype.slice.call(arguments, 1));
    };
    

    Promise#then(onFulFill, onReject)

    Creates a new promise and returns it. If onFulfill or onReject are passed, they are added as SUCCESS/ERROR callbacks to this promise after the nextTick.

    Parameters:

    Returns:

    See:

    Conforms to promises/A+ specification.

    Example:

    var promise = Meetups.find({ tags: 'javascript' }).select('_id').exec();
    promise.then(function (meetups) {
      var ids = meetups.map(function (m) {
        return m._id;
      });
      return People.find({ meetups: { $in: ids }).exec();
    }).then(function (people) {
      if (people.length &lt; 10000) {
        throw new Error('Too few people!!!');
      } else {
        throw new Error('Still need more people!!!');
      }
    }).then(null, function (err) {
      assert.ok(err instanceof Error);
    });
    

  • model.js

    Model#$__delta()

    Produces a special query document of the modified properties used in updates.


    Model#$__version()

    Appends versioning to the where and update clauses.


    Model#$__where()

    Returns a query object which applies shardkeys if they exist.


    Model#$where(argument)

    Creates a Query and specifies a $where condition.

    Parameters:

    • argument <String, Function> is a javascript string or anonymous function

    Returns:

    See:

    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.

    Blog.$where('this.comments.length &gt; 5').exec(function (err, docs) {});
    

    Model#increment()

    Signal that we desire an increment of this documents version.

    See:

    Example:

    Model.findById(id, function (err, doc) {
      doc.increment();
      doc.save(function (err) { .. })
    })
    

    show code

    Model.prototype.increment = function increment () {
      this.$__.version = VERSION_ALL;
      return this;
    }
    

    Model#model(name)

    Returns another Model instance.

    Parameters:

    Example:

    var doc = new Tank;
    doc.model('User').findById(id, callback);
    

    show code

    Model.prototype.model = function model (name) {
      return this.db.model(name);
    };
    

    Model(doc)

    Model constructor

    Parameters:

    • doc <Object> values with which to create the document

    Inherits:

    Events:

    • error: If listening to this event, it is emitted when a document was saved without passing a callback and an error occurred. If not listening, the event bubbles to the connection used to create this Model.

    • index: Emitted after Model#ensureIndexes completes. If an error occurred it is passed with the event.

    Provides the interface to MongoDB collections as well as creates document instances.

    show code

    function Model (doc, fields, skipId) {
      Document.call(this, doc, fields, skipId);
    };
    

    Model#remove([fn])

    Removes this document from the db.

    Parameters:

    Example:

    product.remove(function (err, product) {
      if (err) return handleError(err);
      Product.findById(product._id, function (err, product) {
        console.log(product) // null
      })
    })
    

    show code

    Model.prototype.remove = function remove (fn) {
      if (this.$__.removing) {
        this.$__.removing.addBack(fn);
        return this;
      }
    
      var promise = this.$__.removing = new Promise(fn)
        , where = this.$__where()
        , self = this
        , options = {}
    
      if (this.schema.options.safe) {
        options.safe = this.schema.options.safe;
      }
    
      this.collection.remove(where, options, tick(function (err) {
        if (err) {
          promise.error(err);
          promise = self = self.$__.removing = where = options = null;
          return;
        }
        self.emit('remove', self);
        promise.complete(self);
        promise = self = where = options = null;
      }));
    
      return this;
    };
    

    Model#save([fn])

    Saves this document.

    Parameters:

    See:

    Example:

    product.sold = Date.now();
    product.save(function (err, product, numberAffected) {
      if (err) ..
    })
    

    The callback will receive three parameters, err if an error occurred, product which is the saved product, and numberAffected which will be 1 when the document was found and updated in the database, otherwise 0.

    The fn callback is optional. If no fn is passed and validation fails, the validation error will be emitted on the connection used to create this model.

    var db = mongoose.createConnection(..);
    var schema = new Schema(..);
    var Product = db.model('Product', schema);
    
    db.on('error', handleError);
    

    However, if you desire more local error handling you can add an error listener to the model and handle errors there instead.

    Product.on('error', handleError);
    

    show code

    Model.prototype.save = function save (fn) {
      var promise = new Promise(fn)
        , complete = handleSave(promise, this)
        , options = {};
    
      if (this.schema.options.safe) {
        options.safe = this.schema.options.safe;
      }
    
      if (this.isNew) {
        // send entire doc
        var schemaOptions = utils.clone(this.schema.options);
        schemaOptions.toObject = schemaOptions.toObject || {};
    
        var toObjectOptions = {};
    
        if (schemaOptions.toObject.retainKeyOrder) {
          toObjectOptions.retainKeyOrder = schemaOptions.toObject.retainKeyOrder;
        }
    
        toObjectOptions.depopulate = 1;
    
        var obj = this.toObject(toObjectOptions);
    
        if (!utils.object.hasOwnProperty(obj || {}, '_id')) {
          // documents must have an _id else mongoose won't know
          // what to update later if more changes are made. the user
          // wouldn't know what _id was generated by mongodb either
          // nor would the ObjectId generated my mongodb necessarily
          // match the schema definition.
          return complete(new Error('document must have an _id before saving'));
        }
    
        this.$__version(true, obj);
        this.collection.insert(obj, 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();
    
        if (delta) {
          if (delta instanceof Error) return complete(delta);
          var where = this.$__where(delta[0]);
          this.$__reset();
          this.collection.update(where, delta[1], options, complete);
        } else {
          this.$__reset();
          complete(null);
        }
    
        this.emit('isNew', false);
      }
    };
    

    Model._getSchema(path)

    Finds the schema for path. This is different than
    calling schema.path as it also resolves paths with
    positional selectors (something.$.another.$.path).

    show code

    Model._getSchema = function _getSchema (path) {
      var schema = this.schema
        , pathschema = schema.path(path);
    
      if (pathschema)
        return pathschema;
    
      // look for arrays
      return (function search (parts, schema) {
        var p = parts.length + 1
          , foundschema
          , trypath
    
        while (p--) {
          trypath = parts.slice(0, p).join('.');
          foundschema = schema.path(trypath);
          if (foundschema) {
            if (foundschema.caster) {
    
              // array of Mixed?
              if (foundschema.caster instanceof Types.Mixed) {
                return foundschema.caster;
              }
    
              // Now that we found the array, we need to check if there
              // are remaining document paths to look up for casting.
              // Also we need to handle array.$.path since schema.path
              // doesn't work for that.
              // If there is no foundschema.schema we are dealing with
              // a path like array.$
              if (p !== parts.length && foundschema.schema) {
                if ('$' === parts[p]) {
                  // comments.$.comments.$.title
                  return search(parts.slice(p+1), foundschema.schema);
                } else {
                  // this is the last path of the selector
                  return search(parts.slice(p), foundschema.schema);
                }
              }
            }
            return foundschema;
          }
        }
      })(path.split('.'), schema)
    }
    

    Parameters:

    Returns:


    Model.aggregate([...], [callback])

    Performs aggregations on the models collection.

    show code

    Model.aggregate = function aggregate () {
      var args = [].slice.call(arguments)
        , aggregate
        , callback;
    
      if ('function' === typeof args[args.length - 1]) {
        callback = args.pop();
      }
    
      if (1 === args.length && util.isArray(args[0])) {
        aggregate = new Aggregate(args[0]);
      } else {
        aggregate = new Aggregate(args);
      }
    
      aggregate.bind(this);
    
      if ('undefined' === typeof callback) {
        return aggregate;
      }
    
      return aggregate.exec(callback);
    }
    

    Parameters:

    Returns:

    See:

    If a callback is passed, the aggregate is executed and a Promise is returned. If a callback is not passed, the aggregate itself is returned.

    Example:

    // Find the max balance of all accounts
    Users.aggregate(
        { $group: { _id: null, maxBalance: { $max: '$balance' }}}
      , { $project: { _id: 0, maxBalance: 1 }}
      , function (err, res) {
      if (err) return handleError(err);
      console.log(res); // [ { maxBalance: 98000 } ]
    });
    
    // Or use the aggregation pipeline builder.
    Users.aggregate()
      .group({ _id: null, maxBalance: { $max: '$balance' } })
      .select('-id maxBalance')
      .exec(function (err, res) {
        if (err) return handleError(err);
        console.log(res); // [ { maxBalance: 98 } ]
    });
    

    NOTE:

    • Arguments are not cast to the model’s schema because $project operators allow redefining the “shape” of the documents at any stage of the pipeline, which may leave documents in an incompatible format.
    • The documents returned are plain javascript objects, not mongoose documents (since any shape of document can be returned).
    • Requires MongoDB >= 2.1

    Model.count(conditions, [callback])

    Counts number of matching documents in a database collection.

    show code

    Model.count = function count (conditions, callback) {
      if ('function' === typeof conditions)
        callback = conditions, conditions = {};
    
      // get the mongodb collection object
      var mq = new Query({}, {}, this, this.collection);
    
      return mq.count(conditions, callback);
    };
    

    Parameters:

    Returns:

    Example:

    Adventure.count({ type: 'jungle' }, function (err, count) {
      if (err) ..
      console.log('there are %d jungle adventures', count);
    });
    

    Model.create(doc(s), [fn])

    Shortcut for creating a new Document that is automatically saved to the db if valid.

    show code

    Model.create = function create (doc, fn) {
      var promise = new Promise
        , args
    
      if (Array.isArray(doc)) {
        args = doc;
    
        if ('function' == typeof fn) {
          promise.onResolve(fn);
        }
    
      } else {
        var last  = arguments[arguments.length - 1];
    
        if ('function' == typeof last) {
          promise.onResolve(last);
          args = utils.args(arguments, 0, arguments.length - 1);
        } else {
          args = utils.args(arguments);
        }
      }
    
      var count = args.length;
    
      if (0 === count) {
        promise.complete();
        return promise;
      }
    
      var self = this;
      var docs = [];
    
      args.forEach(function (arg, i) {
        var doc = new self(arg);
        docs[i] = doc;
        doc.save(function (err) {
          if (err) return promise.error(err);
          --count || promise.complete.apply(promise, docs);
        });
      });
    
      return promise;
    };
    

    Parameters:

    Returns:

    Example:

    // pass individual docs
    Candy.create({ type: 'jelly bean' }, { type: 'snickers' }, function (err, jellybean, snickers) {
      if (err) // ...
    });
    
    // pass an array
    var array = [{ type: 'jelly bean' }, { type: 'snickers' }];
    Candy.create(array, function (err, jellybean, snickers) {
      if (err) // ...
    });
    
    // callback is optional; use the returned promise if you like:
    var promise = Candy.create({ type: 'jawbreaker' });
    promise.then(function (jawbreaker) {
      // ...
    })
    

    Model.discriminator(name, schema)

    Adds a discriminator type.

    show code

    Model.discriminator = function discriminator (name, schema) {
      if (!(schema instanceof Schema)) {
        throw new Error("You must pass a valid discriminator Schema");
      }
    
      if (this.schema.discriminatorMapping && !this.schema.discriminatorMapping.isRoot) {
        throw new Error("Discriminator \"" + name + "\" can only be a discriminator of the root model");
      }
    
      var key = this.schema.options.discriminatorKey;
      if (schema.path(key)) {
        throw new Error("Discriminator \"" + name + "\" cannot have field with name \"" + key + "\"");
      }
    
      // merges base schema into new discriminator schema and sets new type field.
      (function mergeSchemas(schema, baseSchema) {
        utils.merge(schema, baseSchema);
    
        var obj = {};
        obj[key] = { type: String, default: name };
        schema.add(obj);
        schema.discriminatorMapping = { key: key, value: name, isRoot: false };
    
        if (baseSchema.options.collection) {
          schema.options.collection = baseSchema.options.collection;
        }
    
          // throws error if options are invalid
        (function validateOptions(a, b) {
          a = utils.clone(a);
          b = utils.clone(b);
          delete a.toJSON;
          delete a.toObject;
          delete b.toJSON;
          delete b.toObject;
    
          if (!utils.deepEqual(a, b)) {
            throw new Error("Discriminator options are not customizable (except toJSON & toObject)");
          }
        })(schema.options, baseSchema.options);
    
        var toJSON = schema.options.toJSON
          , toObject = schema.options.toObject;
    
        schema.options = utils.clone(baseSchema.options);
        if (toJSON)   schema.options.toJSON = toJSON;
        if (toObject) schema.options.toObject = toObject;
    
        schema.callQueue = baseSchema.callQueue.concat(schema.callQueue);
        schema._requiredpaths = undefined; // reset just in case Schema#requiredPaths() was called on either schema
      })(schema, this.schema);
    
      if (!this.discriminators) {
        this.discriminators = {};
      }
    
      if (!this.schema.discriminatorMapping) {
        this.schema.discriminatorMapping = { key: key, value: null, isRoot: true };
      }
    
      if (this.discriminators[name]) {
        throw new Error("Discriminator with name \"" + name + "\" already exists");
      }
    
      this.discriminators[name] = this.db.model(name, schema, this.collection.name);
      this.discriminators[name].prototype.__proto__ = this.prototype;
    
      // apply methods and statics
      applyMethods(this.discriminators[name], schema);
      applyStatics(this.discriminators[name], schema);
    
      return this.discriminators[name];
    };
    
    // Model (class) features
    

    Parameters:

    • name <String> discriminator model name
    • schema <Schema> discriminator model schema

    Example:

    function BaseSchema() {
      Schema.apply(this, arguments);
    
      this.add({
        name: String,
        createdAt: Date
      });
    }
    util.inherits(BaseSchema, Schema);
    
    var PersonSchema = new BaseSchema();
    var BossSchema = new BaseSchema({ department: String });
    
    var Person = mongoose.model('Person', PersonSchema);
    var Boss = Person.discriminator('Boss', BossSchema);
    

    Model.distinct(field, [conditions], [callback])

    Creates a Query for a distinct operation.

    show code

    Model.distinct = function distinct (field, conditions, callback) {
      // get the mongodb collection object
      var mq = new Query({}, {}, this, this.collection);
    
      if ('function' == typeof conditions) {
        callback = conditions;
        conditions = {};
      }
    
      return mq.distinct(conditions, field, callback);
    };
    

    Parameters:

    Returns:

    Passing a callback immediately executes the query.

    Example

    Link.distinct('url', { clicks: {$gt: 100}}, function (err, result) {
      if (err) return handleError(err);
    
      assert(Array.isArray(result));
      console.log('unique urls with more than 100 clicks', result);
    })
    
    var query = Link.distinct('url');
    query.exec(callback);
    

    Model.ensureIndexes([cb])

    Sends ensureIndex commands to mongo for each index declared in the schema.

    show code

    Model.ensureIndexes = function ensureIndexes (cb) {
      var promise = new Promise(cb);
    
      var indexes = this.schema.indexes();
      if (!indexes.length) {
        process.nextTick(promise.fulfill.bind(promise));
        return promise;
      }
    
      // Indexes are created one-by-one to support how MongoDB < 2.4 deals
      // with background indexes.
    
      var self = this
        , safe = self.schema.options.safe
    
      function done (err) {
        self.emit('index', err);
        promise.resolve(err);
      }
    
      function create () {
        var index = indexes.shift();
        if (!index) return done();
    
        var options = index[1];
        options.safe = safe;
        self.collection.ensureIndex(index[0], options, tick(function (err) {
          if (err) return done(err);
          create();
        }));
      }
    
      create();
      return promise;
    }
    

    Parameters:

    Returns:

    Example:

    Event.ensureIndexes(function (err) {
      if (err) return handleError(err);
    });
    

    After completion, an index event is emitted on this Model passing an error if one occurred.

    Example:

    var eventSchema = new Schema({ thing: { type: 'string', unique: true }})
    var Event = mongoose.model('Event', eventSchema);
    
    Event.on('index', function (err) {
      if (err) console.error(err); // error occurred during index creation
    })
    

    NOTE: It is not recommended that you run this in production. Index creation may impact database performance depending on your load. Use with caution.

    The ensureIndex commands are not sent in parallel. This is to avoid the MongoError: cannot add index with a background operation in progress error. See this ticket for more information.


    Model.find(conditions, [projection], [options], [callback])

    Finds documents

    show code

    Model.find = function find (conditions, projection, options, callback) {
      if ('function' == typeof conditions) {
        callback = conditions;
        conditions = {};
        projection = null;
        options = null;
      } else if ('function' == typeof projection) {
        callback = projection;
        projection = null;
        options = null;
      } else if ('function' == typeof options) {
        callback = options;
        options = null;
      }
    
      // get the raw mongodb collection object
      var mq = new Query({}, options, this, this.collection);
      mq.select(projection);
      if (this.schema.discriminatorMapping && mq._selectedInclusively()) {
        mq.select(this.schema.options.discriminatorKey);
      }
    
      return mq.find(conditions, callback);
    };
    

    Parameters:

    Returns:

    See:

    The conditions are cast to their respective SchemaTypes before the command is sent.

    Examples:

    // named john and at least 18
    MyModel.find({ name: 'john', age: { $gte: 18 }});
    
    // executes immediately, passing results to callback
    MyModel.find({ name: 'john', age: { $gte: 18 }}, function (err, docs) {});
    
    // name LIKE john and only selecting the "name" and "friends" fields, executing immediately
    MyModel.find({ name: /john/i }, 'name friends', function (err, docs) { })
    
    // passing options
    MyModel.find({ name: /john/i }, null, { skip: 10 })
    
    // passing options and executing immediately
    MyModel.find({ name: /john/i }, null, { skip: 10 }, function (err, docs) {});
    
    // executing a query explicitly
    var query = MyModel.find({ name: /john/i }, null, { skip: 10 })
    query.exec(function (err, docs) {});
    
    // using the promise returned from executing a query
    var query = MyModel.find({ name: /john/i }, null, { skip: 10 });
    var promise = query.exec();
    promise.addBack(function (err, docs) {});
    

    Model.findById(id, [projection], [options], [callback])

    Finds a single document by id.

    show code

    Model.findById = function findById (id, projection, options, callback) {
      return this.findOne({ _id: id }, projection, options, callback);
    };
    

    Parameters:

    Returns:

    See:

    The id is cast based on the Schema before sending the command.

    Example:

    // find adventure by id and execute immediately
    Adventure.findById(id, function (err, adventure) {});
    
    // same as above
    Adventure.findById(id).exec(callback);
    
    // select only the adventures name and length
    Adventure.findById(id, 'name length', function (err, adventure) {});
    
    // same as above
    Adventure.findById(id, 'name length').exec(callback);
    
    // include all properties except for `length`
    Adventure.findById(id, '-length').exec(function (err, adventure) {});
    
    // passing options (in this case return the raw js objects, not mongoose documents by passing `lean`
    Adventure.findById(id, 'name', { lean: true }, function (err, doc) {});
    
    // same as above
    Adventure.findById(id, 'name').lean().exec(function (err, doc) {});
    

    Model.findByIdAndRemove(id, [options], [callback])

    Issue a mongodb findAndModify remove command by a documents id.

    show code

    Model.findByIdAndRemove = function (id, options, callback) {
      if (1 === arguments.length && 'function' == typeof id) {
        var msg = 'Model.findByIdAndRemove(): First argument must not be a function.
    
    '
                  + '  ' + this.modelName + '.findByIdAndRemove(id, callback)
    '
                  + '  ' + this.modelName + '.findByIdAndRemove(id)
    '
                  + '  ' + this.modelName + '.findByIdAndRemove()
    ';
        throw new TypeError(msg)
      }
    
      return this.findOneAndRemove({ _id: id }, options, callback);
    }
    

    Parameters:

    Returns:

    See:

    Finds a matching document, removes it, passing the found document (if any) to the callback.

    Executes immediately if callback is passed, else a Query object is returned.

    Options:

    • sort: if multiple docs are found by the conditions, sets the sort order to choose which doc to update
    • select: sets the document fields to return

    Examples:

    A.findByIdAndRemove(id, options, callback) // executes
    A.findByIdAndRemove(id, options)  // return Query
    A.findByIdAndRemove(id, callback) // executes
    A.findByIdAndRemove(id) // returns Query
    A.findByIdAndRemove()           // returns Query
    

    Model.findByIdAndUpdate(id, [update], [options], [callback])

    Issues a mongodb findAndModify update command by a documents id.

    show code

    Model.findByIdAndUpdate = function (id, update, options, callback) {
      var args;
      if (1 === arguments.length) {
        if ('function' == typeof id) {
          var msg = 'Model.findByIdAndUpdate(): First argument must not be a function.
    
    '
                    + '  ' + this.modelName + '.findByIdAndUpdate(id, callback)
    '
                    + '  ' + this.modelName + '.findByIdAndUpdate(id)
    '
                    + '  ' + this.modelName + '.findByIdAndUpdate()
    ';
          throw new TypeError(msg)
        }
        return this.findOneAndUpdate({_id: id }, undefined);
      }
    
      args = utils.args(arguments, 1);
    
      // if a model is passed in instead of an id
      if (id && id._id) {
        id = id._id;
      }
      if (id) {
        args.unshift({ _id: id });
      }
      return this.findOneAndUpdate.apply(this, args);
    }
    

    Parameters:

    Returns:

    See:

    Finds a matching document, updates it according to the update arg, passing any options, and returns the found document (if any) to the callback. The query executes immediately if callback is passed else a Query object is returned.

    Options:

    • new: bool - true to return the modified document rather than the original. defaults to true
    • upsert: bool - creates the object if it doesn’t exist. defaults to false.
    • sort: if multiple docs are found by the conditions, sets the sort order to choose which doc to update
    • select: sets the document fields to return

    Examples:

    A.findByIdAndUpdate(id, update, options, callback) // executes
    A.findByIdAndUpdate(id, update, options)  // returns Query
    A.findByIdAndUpdate(id, update, callback) // executes
    A.findByIdAndUpdate(id, update)           // returns Query
    A.findByIdAndUpdate()                     // returns Query
    

    Finds a matching document, updates it according to the update arg, passing any options, and returns the found document (if any) to the callback. The query executes immediately if callback is passed else a Query object is returned.

    Options:

    • new: bool - true to return the modified document rather than the original. defaults to true
    • upsert: bool - creates the object if it doesn’t exist. defaults to false.
    • sort: if multiple docs are found by the conditions, sets the sort order to choose which doc to update

    Note:

    All top level update keys which are not atomic operation names are treated as set operations:

    Example:

    Model.findByIdAndUpdate(id, { name: 'jason borne' }, options, callback)
    
    // is sent as
    Model.findByIdAndUpdate(id, { $set: { name: 'jason borne' }}, options, callback)
    

    This helps prevent accidentally overwriting your document with { name: 'jason borne' }.

    Note:

    Although values are cast to their appropriate types when using the findAndModify helpers, the following are not applied:

    • defaults
    • setters
    • validators
    • middleware

    If you need those features, use the traditional approach of first retrieving the document.

    Model.findById(id, function (err, doc) {
      if (err) ..
      doc.name = 'jason borne';
      doc.save(callback);
    })
    

    Model.findOne([conditions], [projection], [options], [callback])

    Finds one document.

    show code

    Model.findOne = function findOne (conditions, projection, options, callback) {
      if ('function' == typeof options) {
        callback = options;
        options = null;
      } else if ('function' == typeof projection) {
        callback = projection;
        projection = null;
        options = null;
      } else if ('function' == typeof conditions) {
        callback = conditions;
        conditions = {};
        projection = null;
        options = null;
      }
    
      // get the mongodb collection object
      var mq = new Query({}, options, this, this.collection);
      mq.select(projection);
      if (this.schema.discriminatorMapping && mq._selectedInclusively()) {
        mq.select(this.schema.options.discriminatorKey);
      }
    
      return mq.findOne(conditions, callback);
    };
    

    Parameters:

    Returns:

    See:

    The conditions are cast to their respective SchemaTypes before the command is sent.

    Example:

    // find one iphone adventures - iphone adventures??
    Adventure.findOne({ type: 'iphone' }, function (err, adventure) {});
    
    // same as above
    Adventure.findOne({ type: 'iphone' }).exec(function (err, adventure) {});
    
    // select only the adventures name
    Adventure.findOne({ type: 'iphone' }, 'name', function (err, adventure) {});
    
    // same as above
    Adventure.findOne({ type: 'iphone' }, 'name').exec(function (err, adventure) {});
    
    // specify options, in this case lean
    Adventure.findOne({ type: 'iphone' }, 'name', { lean: true }, callback);
    
    // same as above
    Adventure.findOne({ type: 'iphone' }, 'name', { lean: true }).exec(callback);
    
    // chaining findOne queries (same as above)
    Adventure.findOne({ type: 'iphone' }).select('name').lean().exec(callback);
    

    Model.findOneAndRemove(conditions, [options], [callback])

    Issue a mongodb findAndModify remove command.

    show code

    Model.findOneAndRemove = function (conditions, options, callback) {
      if (1 === arguments.length && 'function' == typeof conditions) {
        var msg = 'Model.findOneAndRemove(): First argument must not be a function.
    
    '
                  + '  ' + this.modelName + '.findOneAndRemove(conditions, callback)
    '
                  + '  ' + this.modelName + '.findOneAndRemove(conditions)
    '
                  + '  ' + this.modelName + '.findOneAndRemove()
    ';
        throw new TypeError(msg)
      }
    
      if ('function' == typeof options) {
        callback = options;
        options = undefined;
      }
    
      var fields;
      if (options) {
        fields = options.select;
        options.select = undefined;
      }
    
      var mq = new Query({}, {}, this, this.collection);
      mq.select(fields);
    
      return mq.findOneAndRemove(conditions, options, callback);
    }
    

    Parameters:

    Returns:

    See:

    Finds a matching document, removes it, passing the found document (if any) to the callback.

    Executes immediately if callback is passed else a Query object is returned.

    Options:

    • sort: if multiple docs are found by the conditions, sets the sort order to choose which doc to update
    • select: sets the document fields to return

    Examples:

    A.findOneAndRemove(conditions, options, callback) // executes
    A.findOneAndRemove(conditions, options)  // return Query
    A.findOneAndRemove(conditions, callback) // executes
    A.findOneAndRemove(conditions) // returns Query
    A.findOneAndRemove()           // returns Query
    

    Although values are cast to their appropriate types when using the findAndModify helpers, the following are not applied:

    • defaults
    • setters
    • validators
    • middleware

    If you need those features, use the traditional approach of first retrieving the document.

    Model.findById(id, function (err, doc) {
      if (err) ..
      doc.remove(callback);
    })
    

    Model.findOneAndUpdate([conditions], [update], [options], [callback])

    Issues a mongodb findAndModify update command.

    show code

    Model.findOneAndUpdate = function (conditions, update, options, callback) {
      if ('function' == typeof options) {
        callback = options;
        options = null;
      }
      else if (1 === arguments.length) {
        if ('function' == typeof conditions) {
          var msg = 'Model.findOneAndUpdate(): First argument must not be a function.
    
    '
                  + '  ' + this.modelName + '.findOneAndUpdate(conditions, update, options, callback)
    '
                  + '  ' + this.modelName + '.findOneAndUpdate(conditions, update, options)
    '
                  + '  ' + this.modelName + '.findOneAndUpdate(conditions, update)
    '
                  + '  ' + this.modelName + '.findOneAndUpdate(update)
    '
                  + '  ' + this.modelName + '.findOneAndUpdate()
    ';
          throw new TypeError(msg)
        }
        update = conditions;
        conditions = undefined;
      }
    
      var fields;
      if (options && options.fields) {
        fields = options.fields;
        options.fields = undefined;
      }
    
      update = utils.clone(update, { depopulate: 1 });
      if (this.schema.options.versionKey && options && options.upsert) {
        if (!update.$inc) {
          update.$inc = {};
        }
        update.$inc[this.schema.options.versionKey] = 0;
      }
    
      var mq = new Query({}, {}, this, this.collection);
      mq.select(fields);
    
      return mq.findOneAndUpdate(conditions, update, options, callback);
    }
    

    Parameters:

    Returns:

    See:

    Finds a matching document, updates it according to the update arg, passing any options, and returns the found document (if any) to the callback. The query executes immediately if callback is passed else a Query object is returned.

    Options:

    • new: bool - true to return the modified document rather than the original. defaults to true
    • upsert: bool - creates the object if it doesn’t exist. defaults to false.
    • sort: if multiple docs are found by the conditions, sets the sort order to choose which doc to update
    • select: sets the document fields to return

    Examples:

    A.findOneAndUpdate(conditions, update, options, callback) // executes
    A.findOneAndUpdate(conditions, update, options)  // returns Query
    A.findOneAndUpdate(conditions, update, callback) // executes
    A.findOneAndUpdate(conditions, update)           // returns Query
    A.findOneAndUpdate()                             // returns Query
    

    Note:

    All top level update keys which are not atomic operation names are treated as set operations:

    Example:

    var query = { name: 'borne' };
    Model.findOneAndUpdate(query, { name: 'jason borne' }, options, callback)
    
    // is sent as
    Model.findOneAndUpdate(query, { $set: { name: 'jason borne' }}, options, callback)
    

    This helps prevent accidentally overwriting your document with { name: 'jason borne' }.

    Note:

    Although values are cast to their appropriate types when using the findAndModify helpers, the following are not applied:

    • defaults
    • setters
    • validators
    • middleware

    If you need those features, use the traditional approach of first retrieving the document.

    Model.findOne({ name: 'borne' }, function (err, doc) {
      if (err) ..
      doc.name = 'jason borne';
      doc.save(callback);
    })
    

    Model.geoNear(GeoJSON, options, [callback])

    geoNear support for Mongoose

    show code

    Model.geoNear = function (near, options, callback) {
      if ('function' == typeof options) {
        callback = options;
        options = {};
      }
    
      var promise = new Promise(callback);
      if (!near) {
        promise.error(new Error("Must pass a near option to geoNear"));
        return promise;
      }
    
      var x,y;
    
      if (Array.isArray(near)) {
        if (near.length != 2) {
          promise.error(new Error("If using legacy coordinates, must be an array of size 2 for geoNear"));
          return promise;
        }
        x = near[0];
        y = near[1];
      } else {
        if (near.type != "Point" || !Array.isArray(near.coordinates)) {
          promise.error(new Error("Must pass either a legacy coordinate array or GeoJSON Point to geoNear"));
          return promise;
        }
    
        x = near.coordinates[0];
        y = near.coordinates[1];
      }
    
      var self = this;
      this.collection.geoNear(x, y, options, function (err, res) {
        if (err) return promise.error(err);
        if (options.lean) return promise.fulfill(res.results, res.stats);
    
        var count = res.results.length;
        // if there are no results, fulfill the promise now
        if (count == 0) {
          return promise.fulfill(res.results, res.stats);
        }
    
        var errSeen = false;
        for (var i=0; i < res.results.length; i++) {
          var temp = res.results[i].obj;
          res.results[i].obj = new self();
          res.results[i].obj.init(temp, function (err) {
            if (err && !errSeen) {
              errSeen = true;
              return promise.error(err);
            }
            --count || promise.fulfill(res.results, res.stats);
          });
        }
      });
      return promise;
    };
    

    Parameters:

    • GeoJSON <Object, Array> point or legacy coordinate pair [x,y] to search near
    • options <Object> for the qurery
    • [callback] <Function> optional callback for the query

    Returns:

    See:

    Options:

    • lean {Boolean} return the raw object
    • All options supported by the driver are also supported

    Example:

    // Legacy point
    Model.geoNear([1,3], { maxDistance : 5, spherical : true }, function(err, results, stats) {
       console.log(results);
    });
    
    // geoJson
    var point = { type : "Point", coordinates : [9,9] };
    Model.geoNear(point, { maxDistance : 5, spherical : true }, function(err, results, stats) {
       console.log(results);
    });
    

    Model.geoSearch(condition, options, [callback])

    Implements $geoSearch functionality for Mongoose

    show code

    ``` Model.geoSearch = function (conditions, options, callback) { if (‘function’ == typeof options) {

    callback = options;
    options = {};
    

    }

    var promise = new Promise(callback);

    if (conditions == undefined || !utils.isObject(conditions)) {

    return promise.error(new Error("Must pass conditions to geoSearch"));
    

    }

    if (!options.near) {

    return promise.error(new Error("Must specify the near option in geoSearch"));
    

    }

    if (!Array.isArray(options.near)) {

    return promise.error(new Error("near option must be an array [x, y]"));
    

    }

  // send the conditions in the options object
  options.search = conditions;
  var self = this;

  this.collection.geoHaystackSearch(options.near[0], options.near[1], options, function (err, res) {
    // have to deal with driver problem. Should be fixed in a soon-ish release
    // (7/8/2013)
    if (err || res.errmsg) {
      if (!err) err = new Error(res.errmsg);
      if (res && res.code !== undefined) err.code = res.code;
      return promise.error(err);
    }

    var count = res.results.length;
    if (options.lean || (count == 0)) return promise.fulfill(res.results, res.stats);

    var errSeen = false;
    for (var i=0; i < res.results.length; i++) {
      var temp = res.results[i];
      res.results[i] = new self();
      res.results[i].init(temp, {}, function (err) {
        if (err && !errSeen) {
          errSeen = true;
          return promise.error(err);
        }

        --count || (!errSeen && promise.fulfill(res.results, res.stats));
      });
    }
  });

  return promise;
};
```

#### Parameters:

-   `condition` &lt;[Object](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object)&gt; an object that specifies the match condition (required)
-   `options` &lt;[Object](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object)&gt; for the geoSearch, some (near, maxDistance) are required
-   `[callback]` &lt;[Function](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function)&gt; optional callback

#### Returns:

-   &lt;[Promise](#promise_Promise)&gt;

#### See:

-   [http://docs.mongodb.org/manual/reference/command/geoSearch/](http://docs.mongodb.org/manual/reference/command/geoSearch/)
-   [http://docs.mongodb.org/manual/core/geohaystack/](http://docs.mongodb.org/manual/core/geohaystack/)

#### Example:

```
var options = { near: [10, 10], maxDistance: 5 };
Locations.geoSearch({ type : "house" }, options, function(err, res) {
  console.log(res);
});
```

#### Options:

-   `near` {Array} x,y point to search for
-   `maxDistance` {Number} the maximum distance from the point near that a result can be
-   `limit` {Number} The maximum number of results to return
-   `lean` {Boolean} return the raw object instead of the Mongoose Model

---

### [Model.init()](#model_Model.init)

Called when the model compiles.

show code

```
Model.init = function init () {
  if (this.schema.options.autoIndex) {
    this.ensureIndexes();
  }

  this.schema.emit('init', this);
};
```

---

### [Model.mapReduce(`o`, `[callback]`)](#model_Model.mapReduce)

Executes a mapReduce command.

show code

```
Model.mapReduce = function mapReduce (o, callback) {
  var promise = new Promise(callback);
  var self = this;

  if (!Model.mapReduce.schema) {
    var opts = { noId: true, noVirtualId: true, strict: false }
    Model.mapReduce.schema = new Schema({}, opts);
  }

  if (!o.out) o.out = { inline: 1 };
  if (false !== o.verbose) o.verbose = true;

  o.map = String(o.map);
  o.reduce = String(o.reduce);

  if (o.query) {
    var q = new Query(o.query);
    q.cast(this);
    o.query = q._conditions;
    q = undefined;
  }

  this.collection.mapReduce(null, null, o, function (err, ret, stats) {
    if (err) return promise.error(err);

    if (ret.findOne && ret.mapReduce) {
      // returned a collection, convert to Model
      var model = Model.compile(
          '_mapreduce_' + ret.collectionName
        , Model.mapReduce.schema
        , ret.collectionName
        , self.db
        , self.base);

      model._mapreduce = true;

      return promise.fulfill(model, stats);
    }

    promise.fulfill(ret, stats);
  });

  return promise;
}
```

#### Parameters:

-   `o` &lt;[Object](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object)&gt; an object specifying map-reduce options
-   `[callback]` &lt;[Function](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function)&gt; optional callback

#### Returns:

-   &lt;[Promise](#promise_Promise)&gt;

#### See:

-   [http://www.mongodb.org/display/DOCS/MapReduce](http://www.mongodb.org/display/DOCS/MapReduce)

`o` is an object specifying all mapReduce options as well as the map and reduce functions. All options are delegated to the driver implementation. See [node-mongodb-native mapReduce() documentation](http://mongodb.github.io/node-mongodb-native/api-generated/collection.html#mapreduce) for more detail about options.

#### Example:

```
var o = {};
o.map = function () { emit(this.name, 1) }
o.reduce = function (k, vals) { return vals.length }
User.mapReduce(o, function (err, results) {
  console.log(results)
})
```

#### Other options:

-   `query` {Object} query filter object.
-   `sort` {Object} sort input objects using this key
-   `limit` {Number} max number of documents
-   `keeptemp` {Boolean, default:false} keep temporary data
-   `finalize` {Function} finalize function
-   `scope` {Object} scope variables exposed to map/reduce/finalize during execution
-   `jsMode` {Boolean, default:false} it is possible to make the execution stay in JS. Provided in MongoDB &gt; 2.0.X
-   `verbose` {Boolean, default:false} provide statistics on job execution time.
-   `readPreference` {String}
-   `out*` {Object, default: {inline:1}} sets the output target for the map reduce job.

#### \* out options:

-   `{inline:1}` the results are returned in an array
-   `{replace: 'collectionName'}` add the results to collectionName: the results replace the collection
-   `{reduce: 'collectionName'}` add the results to collectionName: if dups are detected, uses the reducer / finalize functions
-   `{merge: 'collectionName'}` add the results to collectionName: if dups exist the new docs overwrite the old

If `options.out` is set to `replace`, `merge`, or `reduce`, a Model instance is returned that can be used for further querying. Queries run against this model are all executed with the `lean` option; meaning only the js object is returned and no Mongoose magic is applied (getters, setters, etc).

#### Example:

```
var o = {};
o.map = function () { emit(this.name, 1) }
o.reduce = function (k, vals) { return vals.length }
o.out = { replace: 'createdCollectionNameForResults' }
o.verbose = true;

User.mapReduce(o, function (err, model, stats) {
  console.log('map reduce took %d ms', stats.processtime)
  model.find().where('value').gt(10).exec(function (err, docs) {
    console.log(docs);
  });
})

// a promise is returned so you may instead write
var promise = User.mapReduce(o);
promise.then(function (model, stats) {
  console.log('map reduce took %d ms', stats.processtime)
  return model.find().where('value').gt(10).exec();
}).then(function (docs) {
   console.log(docs);
}).then(null, handleError).end()
```

---

### [Model.populate(`docs`, `options`, `[cb(err,doc)]`)](#model_Model.populate)

Populates document references.

show code

```
Model.populate = function (docs, paths, cb) {
  var promise = new Promise(cb);

  // always resolve on nextTick for consistent async behavior
  function resolve () {
    var args = utils.args(arguments);
    process.nextTick(function () {
      promise.resolve.apply(promise, args);
    });
  }

  // normalized paths
  var paths = utils.populate(paths);
  var pending = paths.length;

  if (0 === pending) {
    resolve(null, docs);
    return promise;
  }

  // each path has its own query options and must be executed separately
  var i = pending;
  var path;
  while (i--) {
    path = paths[i];
    populate(this, docs, path, next);
  }

  return promise;

  function next (err) {
    if (err) return resolve(err);
    if (--pending) return;
    resolve(null, docs);
  }
}
```

#### Parameters:

-   `docs` &lt;[Document](#document_Document), [Array](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array)&gt; Either a single document or array of documents to populate.
-   `options` &lt;[Object](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object)&gt; A hash of key/val (path, options) used for population.
-   `[cb(err,doc)]` &lt;[Function](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function)&gt; Optional callback, executed upon completion. Receives \`err\` and the \`doc(s)\`.

#### Returns:

-   &lt;[Promise](#promise_Promise)&gt;

#### Available options:

-   path: space delimited path(s) to populate
-   select: optional fields to select
-   match: optional query conditions to match
-   model: optional name of the model to use for population
-   options: optional query options like sort, limit, etc

#### Examples:

```
// populates a single object
User.findById(id, function (err, user) {
  var opts = [
      { path: 'company', match: { x: 1 }, select: 'name' }
    , { path: 'notes', options: { limit: 10 }, model: 'override' }
  ]

  User.populate(user, opts, function (err, user) {
    console.log(user);
  })
})

// populates an array of objects
User.find(match, function (err, users) {
  var opts = [{ path: 'company', match: { x: 1 }, select: 'name' }]

  var promise = User.populate(users, opts);
  promise.then(console.log).end();
})

// imagine a Weapon model exists with two saved documents:
//   { _id: 389, name: 'whip' }
//   { _id: 8921, name: 'boomerang' }

var user = { name: 'Indiana Jones', weapon: 389 }
Weapon.populate(user, { path: 'weapon', model: 'Weapon' }, function (err, user) {
  console.log(user.weapon.name) // whip
})

// populate many plain objects
var users = [{ name: 'Indiana Jones', weapon: 389 }]
users.push({ name: 'Batman', weapon: 8921 })
Weapon.populate(users, { path: 'weapon' }, function (err, users) {
  users.forEach(function (user) {
    console.log('%s uses a %s', users.name, user.weapon.name)
    // Indiana Jones uses a whip
    // Batman uses a boomerang
  })
})
// Note that we didn't need to specify the Weapon model because
// we were already using it's populate() method.
```

---

### [Model.remove(`conditions`, `[callback]`)](#model_Model.remove)

Removes documents from the collection.

show code

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

  // get the mongodb collection object
  var mq = new Query(conditions, {}, this, this.collection);

  return mq.remove(callback);
};
```

#### Parameters:

-   `conditions` &lt;[Object](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object)&gt;
-   `[callback]` &lt;[Function](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function)&gt;

#### Returns:

-   &lt;[Query](#query-js)&gt;

#### Example:

```
Comment.remove({ title: 'baby born from alien father' }, function (err) {

});
```

#### Note:

To remove documents without waiting for a response from MongoDB, do not pass a `callback`, then call `exec` on the returned [Query](#query-js):

```
var query = Comment.remove({ _id: id });
query.exec();
```

#### Note:

This method sends a remove command directly to MongoDB, no Mongoose documents are involved. Because no Mongoose documents are involved, *no middleware (hooks) are executed*.

---

### [Model.update(`conditions`, `update`, `[options]`, `[callback]`)](#model_Model.update)

Updates documents in the database without returning them.

show code

```
Model.update = function update (conditions, doc, options, callback) {
  var mq = new Query({}, {}, this, this.collection);
  // gh-2406
  // make local deep copy of conditions
  conditions = utils.clone(conditions);
  options = typeof options === 'function' ? options : utils.clone(options);

  return mq.update(conditions, doc, options, callback);
};
```

#### Parameters:

-   `conditions` &lt;[Object](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object)&gt;
-   `update` &lt;[Object](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object)&gt;
-   `[options]` &lt;[Object](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object)&gt;
-   `[callback]` &lt;[Function](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function)&gt;

#### Returns:

-   &lt;[Query](#query-js)&gt;

#### See:

-   [strict](http://mongoosejs.com/docs/guide.html#strict "strict")

#### Examples:

```
MyModel.update({ age: { $gt: 18 } }, { oldEnough: true }, fn);
MyModel.update({ name: 'Tobi' }, { ferret: true }, { multi: true }, function (err, numberAffected, raw) {
  if (err) return handleError(err);
  console.log('The number of updated documents was %d', numberAffected);
  console.log('The raw response from Mongo was ', raw);
});
```

#### 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)
-   `strict` (boolean) overrides the `strict` option for this update
-   `overwrite` (boolean) disables update-only mode, allowing you to overwrite the doc (false)

All `update` values are cast to their appropriate SchemaTypes before being sent.

The `callback` function receives `(err, numberAffected, rawResponse)`.

-   `err` is the error if any occurred
-   `numberAffected` is the count of updated documents Mongo reported
-   `rawResponse` is the full response from Mongo

#### Note:

All top level keys which are not `atomic` operation names are treated as set operations:

#### Example:

```
var query = { name: 'borne' };
Model.update(query, { name: 'jason borne' }, options, callback)

// is sent as
Model.update(query, { $set: { name: 'jason borne' }}, options, callback)
// if overwrite option is false. If overwrite is true, sent without the $set wrapper.
```

This helps prevent accidentally overwriting all documents in your collection with `{ name: 'jason borne' }`.

#### Note:

Be careful to not use an existing model instance for the update clause (this won't work and can cause weird behavior like infinite loops). Also, ensure that the update clause does not have an \_id property, which causes Mongo to return a "Mod on \_id not allowed" error.

#### Note:

To update documents without waiting for a response from MongoDB, do not pass a `callback`, then call `exec` on the returned [Query](#query-js):

```
Comment.update({ _id: id }, { $set: { text: 'changed' }}).exec();
```

#### Note:

Although values are casted to their appropriate types when using update, the following are *not* applied:

-   defaults
-   setters
-   validators
-   middleware

If you need those features, use the traditional approach of first retrieving the document.

```
Model.findOne({ name: 'borne' }, function (err, doc) {
  if (err) ..
  doc.name = 'jason borne';
  doc.save(callback);
})
```

---

### [Model.where(`path`, `[val]`)](#model_Model.where)

Creates a Query, applies the passed conditions, and returns the Query.

show code

```
Model.where = function where (path, val) {
  // get the mongodb collection object
  var mq = new Query({}, {}, this, this.collection).find({});
  return mq.where.apply(mq, arguments);
};
```

#### Parameters:

-   `path` &lt;[String](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String)&gt;
-   `[val]` &lt;[Object](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object)&gt; optional value

#### Returns:

-   &lt;[Query](#query-js)&gt;

For example, instead of writing:

```
User.find({age: {$gte: 21, $lte: 65}}, callback);
```

we can instead write:

```
User.where('age').gte(21).lte(65).exec(callback);
```

Since the Query class also supports `where` you can continue chaining

```
User
.where('age').gte(21).lte(65)
.where('name', /^b/i)
... etc
```

---

### [Model#base](#model_Model-base)

Base Mongoose instance the model uses.

show code

```
Model.base;
```

---

### [Model#collection](#model_Model-collection)

Collection the model uses.

show code

```
Model.prototype.collection;
```

---

### [Model#db](#model_Model-db)

Connection the model uses.

show code

```
Model.prototype.db;
```

---

### [Model#discriminators](#model_Model-discriminators)

Registered discriminators for this model.

show code

```
Model.discriminators;
```

---

### [Model#modelName](#model_Model-modelName)

The name of the model

show code

```
Model.prototype.modelName;
```

---

### [Model#schema](#model_Model-schema)

Schema the model uses.

show code

```
Model.schema;
```

---
  • collection.js

    Collection#addQueue(name, args)

    Queues a method for later execution when its
    database connection opens.

    Parameters:

    • name <String> name of the method to queue
    • args <Array> arguments to pass to the method when executed

    show code

    Collection.prototype.addQueue = function (name, args) {
      this.queue.push([name, args]);
      return this;
    };
    

    Collection(name, conn, opts)

    Abstract Collection constructor

    Parameters:

    • name <String> name of the collection
    • conn <Connection> A MongooseConnection instance
    • opts <Object> optional collection options

    This is the base class that drivers inherit from and implement.

    show code

    function Collection (name, conn, opts) {
      if (undefined === opts) opts = {};
      if (undefined === opts.capped) opts.capped = {};
    
      opts.bufferCommands = undefined === opts.bufferCommands
        ? true
        : opts.bufferCommands;
    
      if ('number' == typeof opts.capped) {
        opts.capped = { size: opts.capped };
      }
    
      this.opts = opts;
      this.name = name;
      this.conn = conn;
      this.queue = [];
      this.buffer = this.opts.bufferCommands;
    
      if (STATES.connected == this.conn.readyState) {
        this.onOpen();
      }
    };
    

    Collection#doQueue()

    Executes all queued methods and clears the queue.

    show code

    Collection.prototype.doQueue = function () {
      for (var i = 0, l = this.queue.length; i < l; i++){
        this[this.queue[i][0]].apply(this, this.queue[i][1]);
      }
      this.queue = [];
      return this;
    };
    

    Collection#ensureIndex()

    Abstract method that drivers must implement.

    show code

    Collection.prototype.ensureIndex = function(){
      throw new Error('Collection#ensureIndex unimplemented by driver');
    };
    

    Collection#find()

    Abstract method that drivers must implement.

    show code

    Collection.prototype.find = function(){
      throw new Error('Collection#find unimplemented by driver');
    };
    

    Collection#findAndModify()

    Abstract method that drivers must implement.

    show code

    Collection.prototype.findAndModify = function(){
      throw new Error('Collection#findAndModify unimplemented by driver');
    };
    

    Collection#findOne()

    Abstract method that drivers must implement.

    show code

    Collection.prototype.findOne = function(){
      throw new Error('Collection#findOne unimplemented by driver');
    };
    

    Collection#getIndexes()

    Abstract method that drivers must implement.

    show code

    Collection.prototype.getIndexes = function(){
      throw new Error('Collection#getIndexes unimplemented by driver');
    };
    

    Collection#insert()

    Abstract method that drivers must implement.

    show code

    Collection.prototype.insert = function(){
      throw new Error('Collection#insert unimplemented by driver');
    };
    

    Collection#mapReduce()

    Abstract method that drivers must implement.

    show code

    Collection.prototype.mapReduce = function(){
      throw new Error('Collection#mapReduce unimplemented by driver');
    };
    

    Collection#onClose()

    Called when the database disconnects

    show code

    Collection.prototype.onClose = function () {
      if (this.opts.bufferCommands) {
        this.buffer = true;
      }
    };
    

    Collection#onOpen()

    Called when the database connects

    show code

    Collection.prototype.onOpen = function () {
      var self = this;
      this.buffer = false;
      self.doQueue();
    };
    

    Collection#save()

    Abstract method that drivers must implement.

    show code

    Collection.prototype.save = function(){
      throw new Error('Collection#save unimplemented by driver');
    };
    

    Collection#update()

    Abstract method that drivers must implement.

    show code

    Collection.prototype.update = function(){
      throw new Error('Collection#update unimplemented by driver');
    };
    

    Collection#conn

    The Connection instance

    show code

    Collection.prototype.conn;
    

    Collection#name

    The collection name

    show code

    Collection.prototype.name;