1. index.js

源码:index.js

1.1. Mongoose#Aggregate()

Mongoose 的 Aggregate 构造函数

1.2. Mongoose#CastError(type, value, path, [reason])

Mongoose 的 CastError 构造函数

参数:
  • type <String> The name of the type
  • value <Any> The value that failed to cast
  • path <String> The path a.b.c in the doc where this cast error occurred
  • [reason] <Error> The original error that was thrown

1.3. Mongoose#Collection()

Mongoose 的 Collection 构造函数

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

打开默认的 mongoose 连接

参数:
  • uri(s) <String>
  • [options] <Object>
  • [options.useMongoClient] <Boolean> 默认为 false,设置为 true 来使用一个新的 mongoose 连接逻辑。
  • [callback] <Function>
返回值:
参见:

如果提供了参数,它们也会被适当地代理到 Connection#open 或者 Connection#openSet

传递的选项优先于连接字符串中包含的选项。

示例:
mongoose.connect('mongodb://user:pass@localhost:port/database');

// 副本集(replica sets)
var uri = 'mongodb://user:pass@localhost:port,anotherhost:port,yetanother:port/mydatabase';
mongoose.connect(uri);

// 使用选项
mongoose.connect(uri, options);

// 连接到多个 mongos
var uri = 'mongodb://hostA:27501,hostB:27501';
var opts = { mongos: true };
mongoose.connect(uri, opts);

// 可选的回调, 当初始化连接完成时被触发
var uri = 'mongodb://nonexistent.domain:27000';
mongoose.connect(uri, function(error) {
  // 如果 error 是真值,那初始化连接失败
})
源码
  Mongoose.prototype.connect = function() {
    var conn = this.connection;
    if ((arguments.length === 2 || arguments.length === 3) &&
        typeof arguments[0] === 'string' &&
        typeof arguments[1] === 'object' &&
        arguments[1].useMongoClient === true) {
      return conn.openUri(arguments[0], arguments[1], arguments[2]);
    }
    if (rgxReplSet.test(arguments[0]) || checkReplicaSetInUri(arguments[0])) {
      return new MongooseThenable(this, conn.openSet.apply(conn, arguments));
    }

    return new MongooseThenable(this, conn.open.apply(conn, arguments));
  };
  Mongoose.prototype.connect.$hasSideEffects = true;

1.5. Mongoose#Connection()

Mongoose 的 Connection 构造函数

1.6. Mongoose#createConnection([uri], [options], [options.config], [options.config.autoIndex], [options.useMongoClient])

创建一个 Connection 实例。

参数:
  • [uri] <String> a mongodb:// URI
  • [options] <Object> options to pass to the driver
  • [options.config] <Object> mongoose-specific options
  • [options.config.autoIndex] <Boolean> set to false to disable automatic index creation for all models associated with this connection.
  • [options.useMongoClient] <Boolean> false by default, set to true to use new mongoose connection logic
返回值:
  • <Connection, Promise> the created Connection object, or promise that resolves to the connection if useMongoClient option specified.
参见:

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.

示例:
// with mongodb:// URI
db = mongoose.createConnection('mongodb://user:pass@localhost:port/database');

// and options
var opts = { db: { native_parser: true }}
db = mongoose.createConnection('mongodb://user:pass@localhost:port/database', opts);

// replica sets
db = mongoose.createConnection('mongodb://user:pass@localhost:port,anotherhost:port,yetanother:port/database');

// and options
var opts = { replset: { strategy: 'ping', rs_name: 'testSet' }}
db = mongoose.createConnection('mongodb://user:pass@localhost:port,anotherhost:port,yetanother:port/database', opts);

// with [host, database_name[, port] signature
db = mongoose.createConnection('localhost', 'database', port)

// and options
var opts = { server: { auto_reconnect: false }, user: 'username', pass: 'mypassword' }
db = mongoose.createConnection('localhost', 'database', port, opts)

// initialize now, connect later
db = mongoose.createConnection();
db.open('localhost', 'database', port, [opts]);
源码
  Mongoose.prototype.createConnection = function(uri, options) {
    var conn = new Connection(this);
    this.connections.push(conn);

    var rsOption = options && (options.replset || options.replSet);

    if (options && options.useMongoClient) {
      return conn.openUri(uri, options);
    }

    if (arguments.length) {
      if (rgxReplSet.test(arguments[0]) || checkReplicaSetInUri(arguments[0])) {
        conn._openSetWithoutPromise.apply(conn, arguments);
      } else if (rsOption &&
          (rsOption.replicaSet || rsOption.rs_name)) {
        conn._openSetWithoutPromise.apply(conn, arguments);
      } else {
        conn._openWithoutPromise.apply(conn, arguments);
      }
    }

    return conn;
  };
  Mongoose.prototype.createConnection.$hasSideEffects = true;

1.7. Mongoose#disconnect([fn])

断开所有连接。

参数:
  • [fn] <Function> called after all connection close.
返回值:
源码
  Mongoose.prototype.disconnect = function(fn) {
    var _this = this;

    var Promise = PromiseProvider.get();
    return new MongooseThenable(this, new Promise.ES6(function(resolve, reject) {
      var remaining = _this.connections.length;
      if (remaining <= 0) {
        fn && fn();
        resolve();
        return;
      }
      _this.connections.forEach(function(conn) {
        conn.close(function(error) {
          if (error) {
            fn && fn(error);
            reject(error);
            return;
          }
          if (!--remaining) {
            fn && fn();
            resolve();
          }
        });
      });
    }));
  };
  Mongoose.prototype.disconnect.$hasSideEffects = true;

1.8. Mongoose#Document()

Mongoose 的 Document 构造函数

1.9. Mongoose#DocumentProvider()

Mongoose 的 DocumentProvider 构造函数

1.10. Mongoose#Error()

MongooseError 构造函数。

1.11. Mongoose#get(key)

获取 mongoose 选项。

参数:
示例:
mongoose.get('test') // returns the 'test' value

1.12. Mongoose#getPromiseConstructor()

返回当前的 ES6 样式的 promise 构造函数。在 Mongoose 4.x 中,等价于 mongoose.Promise.ES6,但是一旦我们去掉了 .ES6 位,就会改变。

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

定义一个模型或检索它。

参数:
  • name <String, Function>model name or class extending Model
  • [schema]
  • collection <String> name (optional, inferred 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.

示例:
var mongoose = require('mongoose');

// 使用 mongoose 示例定义一个 Actor 模型
mongoose.model('Actor', new Schema({ name: String }));

// 创建一个新连接
var conn = mongoose.createConnection(..);

// 检索 Actor 模型
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.

示例:
var schema = new Schema({ name: String }, { collection: 'actor' });

// or

schema.set('collection', 'actor');

// or

var collectionName = 'actor'
var M = mongoose.model('Actor', schema, collectionName)
源码
Mongoose.prototype.model = function(name, schema, collection, skipInit) {
  var model;
  if (typeof name === 'function') {
    model = name;
    name = model.name;
    if (!(model.prototype instanceof Model)) {
      throw new mongoose.Error('The provided class ' + name + ' must extend Model');
    }
  }

  if (typeof schema === 'string') {
    collection = schema;
    schema = false;
  }

  if (utils.isObject(schema) && !(schema.instanceOfSchema)) {
    schema = new Schema(schema);
  }
  if (schema && !schema.instanceOfSchema) {
    throw new Error('The 2nd parameter to `mongoose.model()` should be a ' +
      'schema or a POJO');
  }

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

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

  // look up schema for the collection.
  if (!this.modelSchemas[name]) {
    if (schema) {
      // cache it so we only apply plugins once
      this.modelSchemas[name] = schema;
    } else {
      throw new mongoose.Error.MissingSchemaError(name);
    }
  }

  if (schema) {
    this._applyPlugins(schema);
  }

  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] && options.cache !== false) {
    if (schema && schema.instanceOfSchema && schema !== this.models[name].schema) {
      throw new mongoose.Error.OverwriteModelError(name);
    }

    if (collection) {
      // subclass current model with alternate collection
      model = this.models[name];
      schema = model.prototype.schema;
      sub = model.__subclass(this.connection, schema, collection);
      // do not cache the sub model
      return sub;
    }

    return this.models[name];
  }

  // ensure a schema exists
  if (!schema) {
    schema = this.modelSchemas[name];
    if (!schema) {
      throw new mongoose.Error.MissingSchemaError(name);
    }
  }

  // Apply relevant "global" options to the schema
  if (!('pluralization' in schema.options)) schema.options.pluralization = this.options.pluralization;


  if (!collection) {
    collection = schema.get('collection') || format(name, schema.options);
  }

  var connection = options.connection || this.connection;
  model = this.Model.compile(model || name, schema, collection, connection, this);

  if (!skipInit) {
    model.init();
  }

  if (options.cache === false) {
    return model;
  }

  this.models[name] = model;
  return this.models[name];
};
Mongoose.prototype.model.$hasSideEffects = true;

1.14. Mongoose#Model()

Mongoose Model 构造函数。

1.15. Mongoose#modelNames()

返回一个在 Mongoose 实例上创建的模型名称数组。

返回值:
注意:

不包括使用 connection.model() 创建的模型的名称。

源码
Mongoose.prototype.modelNames = function() {
  var names = Object.keys(this.models);
  return names;
};
Mongoose.prototype.modelNames.$hasSideEffects = true;

1.16. Mongoose()

Mongoose 构造函数。

mongoose 模块的导出对象(exports)是该类的一个实例。大多数应用程序只会使用这个实例。

源码
function Mongoose() {
  this.connections = [];
  this.models = {};
  this.modelSchemas = {};
  // default global options
  this.options = {
    pluralization: true
  };
  var conn = this.createConnection(); // default connection
  conn.models = this.models;

  Object.defineProperty(this, 'plugins', {
    configurable: false,
    enumerable: true,
    writable: false,
    value: [
      [saveSubdocs, { deduplicate: true }],
      [validateBeforeSave, { deduplicate: true }],
      [shardingPlugin, { deduplicate: true }]
    ]
  });
}

1.17. Mongoose#Mongoose()

Mongoose 构造函数

mongoose 模块的导出对象(exports)是该类的一个实例。大多数应用程序只会使用这个实例。

示例:
  var mongoose = require('mongoose');
  var mongoose2 = new mongoose.Mongoose();

1.18. Mongoose#plugin(fn, [opts])

声明一个在所有模式上执行的全局插件。

参数:
返回值:
参见:

等效于在创建的每个模式上调用 .plugin(fn)

源码
Mongoose.prototype.plugin = function(fn, opts) {
  this.plugins.push([fn, opts]);
  return this;
};
Mongoose.prototype.plugin.$hasSideEffects = true;

1.19. function Object() { [native code] }#Promise()

Mongoose Promise 构造函数。

1.20. Mongoose#PromiseProvider()

mongoose promises 的储存层

1.21. Mongoose#Query()

Mongoose Query 构造函数。

1.22. Mongoose#Schema()

Mongoose Schema 构造函数

示例:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var CatSchema = new Schema(..);

1.23. Mongoose#SchemaType()

Mongoose SchemaType 构造函数

1.24. Mongoose#set(key, value)

设置 mongoose 的选项

参数:
示例:
mongoose.set('test', value) // 设置 'test' 选项为 `value`

mongoose.set('debug', true) // enable logging collection methods + arguments to the console

mongoose.set('debug', function(collectionName, methodName, arg1, arg2...) {}); // use custom function to log collection methods + arguments
源码
Mongoose.prototype.set = function(key, value) {
  if (arguments.length === 1) {
    return this.options[key];
  }

  this.options[key] = value;
  return this;
};
Mongoose.prototype.set.$hasSideEffects = true;

()

为用户空间(user-land)暴露连接状态

源码
Mongoose.prototype.STATES = STATES;

1.25. Mongoose#VirtualType()

Mongoose VirtualType 构造函数

1.26. Mongoose#connection

mongoose 模块的默认连接。

示例:
var mongoose = require('mongoose');
mongoose.connect(...);
mongoose.connection.on('error', cb);

这是为使用 mongoose.model 创建的每个模型所默认使用的连接。

源码
```
<!--endsec-->

##### 返回值:

  * &lt;[Connection][]&gt;

## Mongoose#mongo

Mongoose 使用的[原生的 node-mongodb 驱动器](https://github.com/mongodb/node-mongodb-native)。

<!--sec data-title="源码" data-id="sec_Mongoose_mongo" data-show=true data-collapse=true ces-->
```js
Mongoose.prototype.mongo = require('mongodb');

1.27. Mongoose#mquery

Mongoose 使用的 mquery 查询构建器。

源码
Mongoose.prototype.mquery = require('mquery');

1.28. Mongoose#SchemaTypes

各种各样的 Mongoose SchemaTypes。

注意:

用于向后兼容的 mongoose.Schema.Types 的别名。

源码
Mongoose.prototype.SchemaTypes = Schema.Types;
参见:

1.29. Mongoose#Types

各种各样的 Mongoose Types.

示例:
var mongoose = require('mongoose');
var array = mongoose.Types.Array;
类型:

使用这个暴露来对 ObjectId 类型进行访问,我们可以根据需要构造 id

var ObjectId = mongoose.Types.ObjectId;
var id1 = new ObjectId;
源码
Mongoose.prototype.Types = Types;

1.30. Mongoose#version

Mongoose 版本

源码
Mongoose.prototype.version = pkg.version;

2. types/array.js

2.1. MongooseArray#$shift()

在每一个文档 save() 的情况下,自动地 shift 这个数组最多一次。

参见:
注意:

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.

doc.array = [1,2,3];

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

 // no affect
 shifted = doc.array.$shift();
 console.log(doc.array); // [2,3]

 doc.save(function (err) {
   if (err) return handleError(err);

   // we saved, now $shift works again
   shifted = doc.array.$shift();
   console.log(shifted ); // 2
   console.log(doc.array); // [3]
 })

2.2. MongooseArray#remove()

pull 的别名。

参见:

2.3. MongooseArray.$pop()

在每一个文档 save() 的情况下,自动地 pop 这个数组最多一次。

参见:
注意:

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.

doc.array = [1,2,3];

 var popped = doc.array.$pop();
 console.log(popped); // 3
 console.log(doc.array); // [1,2]

 // no affect
 popped = doc.array.$pop();
 console.log(doc.array); // [1,2]

 doc.save(function (err) {
   if (err) return handleError(err);

   // we saved, now $pop works again
   popped = doc.array.$pop();
   console.log(popped); // 2
   console.log(doc.array); // [1]
 })

2.4. MongooseArray.addToSet([args...])

如果不存在,则将值添加到数组中。

参数:
  • [args...]
返回值:
  • <Array> the values that were added
示例:
console.log(doc.array) // [2,3,4]
var added = doc.array.addToSet(4,5);
console.log(doc.array) // [2,3,4,5]
console.log(added)     // [5]

2.5. MongooseArray.indexOf(obj)

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

参数:

obj <Object> the item to look for

返回值:

2.6. MongooseArray.inspect()

Helper for console.log

2.7. MongooseArray.nonAtomicPush([args...])

Pushes items to the array non-atomically.

参数:
  • [args...]
注意:

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.

2.8. MongooseArray.pop()

Wraps Array#pop with proper change tracking.

参见:
注意:

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.

2.9. MongooseArray.pull([args...])

Pulls items from the array atomically. Equality is determined by casting the provided value to an embedded document and comparing using

the Document.equals() function.

参数:
  • [args...]
参见:
  • mongodb
示例:
doc.array.pull(ObjectId)
doc.array.pull({ _id: 'someId' })
doc.array.pull(36)
doc.array.pull('tag 1', 'tag 2')

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

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

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

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

The first pull call will result in a atomic operation on the database, if pull is called repeatedly without saving the document, a $set operation is used on the complete array instead, overwriting possible changes that happened on the database in the meantime.

2.10. MongooseArray.push([args...])

Wraps Array#push with proper change tracking.

参数:

2.11. MongooseArray.set()

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

返回值:
示例:
// given documents based on the following
var Doc = mongoose.model('Doc', new Schema({ array: [Number] }));

var doc = new Doc({ array: [2,3,4] })

console.log(doc.array) // [2,3,4]

doc.array.set(1,"5");
console.log(doc.array); // [2,5,4] // properly cast to number
doc.save() // the change is saved

// VS not using array#set
doc.array[1] = "5";
console.log(doc.array); // [2,"5",4] // no casting
doc.save() // change is not saved

2.12. MongooseArray.shift()

Wraps Array#shift with proper change tracking.

示例:
doc.array = [2,3];
var res = doc.array.shift();
console.log(res) // 2
console.log(doc.array) // [3]
注意:

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.

2.13. MongooseArray.sort()

使用适当的变化跟踪包装了 Array#sort

注意:

将整个数组标记为修改,如果保存,将作为 $set 操作存储它,可能会覆盖在检索对象和保存它时发生的任何更改。

2.14. MongooseArray.splice()

Wraps Array#splice with proper change tracking and casting.

注意:

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.

2.15. MongooseArray.toObject(options)

Returns a native js Array.

参数:
返回值:

2.16. MongooseArray.unshift()

Wraps Array#unshift with proper change tracking.

注意:

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.

3. types/subdocument.js

源码:types/subdocument.js

3.1. Subdocument#ownerDocument()

Returns the top level document of this sub-document.

返回值:
源码
Subdocument.prototype.ownerDocument = function() {
  if (this.$__.ownerDocument) {
    return this.$__.ownerDocument;
  }

  var parent = this.$parent;
  if (!parent) {
    return this;
  }

  while (parent.$parent || parent.__parent) {
    parent = parent.$parent || parent.__parent;
  }
  this.$__.ownerDocument = parent;
  return this.$__.ownerDocument;
};

3.2. Subdocument#parent()

Returns this sub-documents parent document.

源码
Subdocument.prototype.parent = function() {
  return this.$parent;
};

3.3. Subdocument#remove([options], [callback])

Null-out this subdoc

参数:
  • [options] <Object>
  • [callback] <Function> optional callback for compatibility with Document.prototype.remove
源码
Subdocument.prototype.remove = function(options, callback) {
  if (typeof options === 'function') {
    callback = options;
    options = null;
  }

  registerRemoveListener(this);

  // If removing entire doc, no need to remove subdoc
  if (!options || !options.noop) {
    this.$parent.set(this.$basePath, null);
  }

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

4. types/embedded.js

源码:types/embedded.js

4.1. EmbeddedDocument#inspect()

Helper for console.log

源码
EmbeddedDocument.prototype.inspect = function() {
  return this.toObject({
    transform: false,
    retainKeyOrder: true,
    virtuals: false,
    flattenDecimals: false
  });
};

4.2. EmbeddedDocument#invalidate(path, err)

Marks a path as invalid, causing validation to fail.

参数:
  • path <String> the field to invalidate
  • err error which states the reason path was invalid
返回值:
源码
EmbeddedDocument.prototype.invalidate = function(path, err, val, first) {
  if (!this.__parent) {
    Document.prototype.invalidate.call(this, path, err, val);
    if (err.$isValidatorError) {
      return true;
    }
    throw err;
  }

  var index = this.__index;
  if (typeof index !== 'undefined') {
    var parentPath = this.__parentArray._path;
    var fullPath = [parentPath, index, path].join('.');
    this.__parent.invalidate(fullPath, err, val);
  }

  if (first) {
    this.$__.validationError = this.ownerDocument().$__.validationError;
  }

  return true;
};

4.3. EmbeddedDocument#ownerDocument()

Returns the top level document of this sub-document.

返回值:
源码
EmbeddedDocument.prototype.ownerDocument = function() {
  if (this.$__.ownerDocument) {
    return this.$__.ownerDocument;
  }

  var parent = this.__parent;
  if (!parent) {
    return this;
  }

  while (parent.__parent || parent.$parent) {
    parent = parent.__parent || parent.$parent;
  }

  this.$__.ownerDocument = parent;
  return this.$__.ownerDocument;
};

4.4. EmbeddedDocument#parent()

Returns this sub-documents parent document.

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

4.5. EmbeddedDocument#parentArray()

Returns this sub-documents parent array.

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

4.6. EmbeddedDocument#remove([options], [fn])

Removes the subdocument from its parent array.

参数:
源码
EmbeddedDocument.prototype.remove = function(options, fn) {
  if ( typeof options === 'function' && !fn ) {
    fn = options;
    options = undefined;
  }
  if (!this.__parentArray || (options && options.noop)) {
    fn && fn(null);
    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;
};

4.7. EmbeddedDocument.markModified(path)

Marks the embedded doc modified.

源码
EmbeddedDocument.prototype.markModified = function(path) {
  this.$__.activePaths.modify(path);
  if (!this.__parentArray) {
    return;
  }

  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);
  }
};
参数:
  • path <String> the path which changed
示例:
var doc = blogpost.comments.id(hexstring);
doc.mixed.type = 'changed';
doc.markModified('mixed.type');

5. types/buffer.js

源码:types/buffer.js

5.1. MongooseBuffer.copy(target)

Copies the buffer.

参数:
* target &lt;[Buffer][]&gt;
返回值:
* &lt;[Number][]&gt; The number of bytes copied.
注意:

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. *

5.2. MongooseBuffer.equals(other)

Determines if this buffer is equals to other buffer

参数:
返回值:

5.3. MongooseBuffer.subtype(subtype)

Sets the subtype option and marks the buffer modified.

参数:
  • subtype
参见:
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);

5.4. MongooseBuffer.toBSON()

Converts this buffer for storage in MongoDB, including subtype

返回值:

5.5. MongooseBuffer.toObject([subtype])

Converts this buffer to its Binary type representation.

参数:
  • [subtype]
返回值:
参见:
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);

5.6. MongooseBuffer.write()

Writes the buffer.


6. types/objectid.js

源码:types/objectid.js

6.1. ObjectId()

ObjectId type constructor

示例:
var id = new mongoose.Types.ObjectId;

7. types/decimal128.js

源码:types/decimal128.js

7.1. exports()

ObjectId type constructor

示例:
var id = new mongoose.Types.ObjectId;

8. types/documentarray.js

源码:types/documentarray.js

8.1. MongooseDocumentArray.create(obj)

Creates a subdocument casted to this schema.

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

This is the same subdocument constructor used for casting.

8.2. MongooseDocumentArray.id(id)

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

参数:
  • id

    返回值:
  • the subdocument or null if not found.

示例:
var embeddedDoc = m.array.id(some_id);

8.3. MongooseDocumentArray.inspect()

Helper for console.log

8.4. MongooseDocumentArray.toObject([options])

Returns a native js Array of plain js objects

参数:
  • [options] <Object> optional options to pass to each documents toObject method call during conversion
返回值:
注意:

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

9. promise.js

源码:promise.js

9.1. Promise#addBack(listener)

Adds a single function as a listener to both err and complete.

参数:
返回值:

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');
})

mpromise#onResolve 的别名。

Deprecated. Use onResolve instead.

9.2. Promise#addCallback(listener)

Adds a listener to the complete (success) event.

参数:
返回值:

mpromise#onFulfill 的别名。

Deprecated. Use onFulfill instead.

9.3. Promise#addErrback(listener)

Adds a listener to the err (rejected) event.

参数:
返回值:

Deprecated. Use onReject instead.

9.4. Promise#catch(onReject)

ES6-style .catch() shorthand

参数:
返回值:

9.5. 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.

参见:
示例:
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);

9.6. Promise#error(err)

Rejects this promise with err.

参数:
  • err
返回值:

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.

源码
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);
};

9.7. Promise#on(event, listener)

Adds listener to the event.

参数:
返回值:
参见:

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.

9.8. Promise(fn)

Promise constructor.

参数:
  • fn <Function> a function which will be called when the promise is resolved that accepts fn(err, ...){} as signature
继承:
事件:
  • err: Emits when the promise is rejected

  • complete: Emits when the promise is fulfilled

Promises are returned from executed queries.示例:

var query = Candy.find({ bar: true });
var promise = query.exec();

DEPRECATED. Mongoose 5.0 will use native promises by default (or bluebird, if native promises are not present) but still support plugging in your own ES6-compatible promises library. Mongoose 5.0 will notsupport mpromise.

源码
function Promise(fn) {
  MPromise.call(this, fn);
}

9.9. Promise#reject(reason)

Rejects this promise with reason.

参数:
  • reason
返回值:
参见:

If the promise has already been fulfilled or rejected, not action is taken.

9.10. Promise#resolve([err], [val])

Resolves this promise to a rejected state if err is passed or a fulfilled state if no err is passed.

参数:
  • [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.

注意:

overrides mpromise#resolve to provide error casting.

源码
Promise.prototype.resolve = function(err) {
  if (err) return this.error(err);
  return this.fulfill.apply(this, Array.prototype.slice.call(arguments, 1));
};

9.11. 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.

参数:
返回值:
参见:

Conforms to promises/A+ specification.

示例:
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);
});

9.12. Promise.complete(args)

Fulfills this promise with passed arguments.

参数:
  • args

mpromise#fulfill 的别名。

Deprecated. Use fulfill instead.

9.13. Promise.ES6(resolver)

ES6-style promise constructor wrapper around mpromise.

源码
Promise.ES6 = function(resolver) {
  var promise = new Promise();

  // No try/catch for backwards compatibility
  resolver(
    function() {
      promise.complete.apply(promise, arguments);
    },
    function(e) {
      promise.error(e);
    });

  return promise;
};
参数:
返回值:

9.14. Promise.fulfill(args)

Fulfills this promise with passed arguments.

参数:
  • args
参见:

10. virtualtype.js

源码:virtualtype.js

10.1. VirtualType()

VirtualType constructor

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

示例:
var fullname = schema.virtual('fullname');
fullname instanceof mongoose.VirtualType // true
源码
function VirtualType(options, name) {
  this.path = name;
  this.getters = [];
  this.setters = [];
  this.options = options || {};
}

10.2. VirtualType#get(fn)

Defines a getter.

参数:
返回值:
  • this
示例:
var virtual = schema.virtual('fullname');
virtual.get(function () {
  return this.name.first + ' ' + this.name.last;
});
源码
VirtualType.prototype.get = function(fn) {
  this.getters.push(fn);
  return this;
};

10.3. VirtualType#set(fn)

Defines a setter.

参数:
返回值:
  • this
示例:
var virtual = schema.virtual('fullname');
virtual.set(function (v) {
  var parts = v.split(' ');
  this.name.first = parts[0];
  this.name.last = parts[1];
});
源码
VirtualType.prototype.set = function(fn) {
  this.setters.push(fn);
  return this;
};

10.4. VirtualType#applyGetters(value, scope)

Applies getters to value using optional scope.

参数:
返回值:
  • the value after applying all getters
源码
VirtualType.prototype.applyGetters = function(value, scope) {
  var v = value;
  for (var l = this.getters.length - 1; l >= 0; l--) {
    v = this.getters[l].call(scope, v, this);
  }
  return v;
};

10.5. VirtualType#applySetters(value, scope)

Applies setters to value using optional scope.

参数:
返回值:
  • the value after applying all setters
源码
VirtualType.prototype.applySetters = function(value, scope) {
  var v = value;
  for (var l = this.setters.length - 1; l >= 0; l--) {
    v = this.setters[l].call(scope, v, this);
  }
  return v;
};

11. utils.js

源码:utils.js

11.1. exports.pluralization

Pluralization rules.

源码
exports.pluralization = [
  [/(m)an$/gi, '$1en'],
  [/(pe)rson$/gi, '$1ople'],
  [/(child)$/gi, '$1ren'],
  [/^(ox)$/gi, '$1en'],
  [/(ax|test)is$/gi, '$1es'],
  [/(octop|vir)us$/gi, '$1i'],
  [/(alias|status)$/gi, '$1es'],
  [/(bu)s$/gi, '$1ses'],
  [/(buffal|tomat|potat)o$/gi, '$1oes'],
  [/([ti])um$/gi, '$1a'],
  [/sis$/gi, 'ses'],
  [/(?:([^f])fe|([lr])f)$/gi, '$1$2ves'],
  [/(hive)$/gi, '$1s'],
  [/([^aeiouy]|qu)y$/gi, '$1ies'],
  [/(x|ch|ss|sh)$/gi, '$1es'],
  [/(matr|vert|ind)ix|ex$/gi, '$1ices'],
  [/([m|l])ouse$/gi, '$1ice'],
  [/(kn|w|l)ife$/gi, '$1ives'],
  [/(quiz)$/gi, '$1zes'],
  [/s$/gi, 's'],
  [/([^a-z])$/, '$1'],
  [/$/gi, 's']
];
var rules = exports.pluralization;

These rules are applied while processing the argument to toCollectionName.

11.2. exports.uncountables

Uncountable words.

源码
exports.uncountables = [
  'advice',
  'energy',
  'excretion',
  'digestion',
  'cooperation',
  'health',
  'justice',
  'labour',
  'machinery',
  'equipment',
  'information',
  'pollution',
  'sewage',
  'paper',
  'money',
  'species',
  'series',
  'rain',
  'rice',
  'fish',
  'sheep',
  'moose',
  'deer',
  'news',
  'expertise',
  'status',
  'media'
];
var uncountables = exports.uncountables;

These words are applied while processing the argument to toCollectionName.


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

源码:drivers/node-mongodb-native/collection.js

12.1. function Object() { [native code] }#$format()

Formatter for debug print args

12.2. function Object() { [native code] }#$print(

Debug print helper

12.3. NativeCollection#getIndexes(callback)

Retreives information about this collections indexes.

参数:

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

源码:drivers/node-mongodb-native/connection.js

13.1. NativeConnection#useDb(name)

Switches to a different database using the same connection pool.

参数:
  • name <String> The database name
返回值:

Returns a new connection object, with the new db.

源码
NativeConnection.prototype.useDb = function(name) {
  // we have to manually copy all of the attributes...
  var newConn = new this.constructor();
  newConn.name = name;
  newConn.base = this.base;
  newConn.collections = {};
  newConn.models = {};
  newConn.replica = this.replica;
  newConn.hosts = this.hosts;
  newConn.host = this.host;
  newConn.port = this.port;
  newConn.user = this.user;
  newConn.pass = this.pass;
  newConn.options = this.options;
  newConn._readyState = this._readyState;
  newConn._closeCalled = this._closeCalled;
  newConn._hasOpened = this._hasOpened;
  newConn._listening = false;

  // First, when we create another db object, we are not guaranteed to have a
  // db object to work with. So, in the case where we have a db object and it
  // is connected, we can just proceed with setting everything up. However, if
  // we do not have a db or the state is not connected, then we need to wait on
  // the 'open' event of the connection before doing the rest of the setup
  // the 'connected' event is the first time we'll have access to the db object

  var _this = this;

  if (this.db && this._readyState === STATES.connected) {
    wireup();
  } else {
    this.once('connected', wireup);
  }

  function wireup() {
    newConn.db = _this.db.db(name);
    newConn.onOpen();
    // setup the events appropriately
    listen(newConn);
  }

  newConn.name = name;

  // push onto the otherDbs stack, this is used when state changes
  this.otherDbs.push(newConn);
  newConn.otherDbs.push(this);

  return newConn;
};

13.2. NativeConnection.STATES

Expose the possible connection states.

源码
NativeConnection.STATES = STATES;

14. browser.js

源码:browser.js

14.1. function Object() { [native code] }#Promise()

The Mongoose Promise constructor.

14.2. exports.Document()

The Mongoose browser Document constructor.

14.3. exports.Error()

The MongooseError constructor.

14.4. exports.PromiseProvider()

Storage layer for mongoose promises

14.5. exports.Schema()

The Mongoose Schema constructor

示例:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var CatSchema = new Schema(..);

14.6. exports.VirtualType()

The Mongoose VirtualType constructor

14.7. exports#SchemaTypes

The various Mongoose SchemaTypes.

注意:

Alias of mongoose.Schema.Types for backwards compatibility.

源码
exports.SchemaType = require('./schematype.js');
参见:

14.8. exports#Types

The various Mongoose Types.

示例:
var mongoose = require('mongoose');
var array = mongoose.Types.Array;
类型:

Using this exposed access to the ObjectId type, we can construct ids on demand.

var ObjectId = mongoose.Types.ObjectId;
var id1 = new ObjectId;
源码
exports.Types = require('./types');

15. ES6Promise.js

源码:ES6Promise.js

15.1. ES6Promise(fn)

ES6 Promise wrapper constructor.

参数:
  • fn <Function> a function which will be called when the promise is resolved that accepts fn(err, ...){} as signature

Promises are returned from executed queries.

示例:
var query = Candy.find({ bar: true });
var promise = query.exec();

DEPRECATED. Mongoose 5.0 will use native promises by default (or bluebird, if native promises are not present) but still support plugging in your own ES6-compatible promises library. Mongoose 5.0 will not support mpromise.

源码
function ES6Promise() {
  throw new Error('Can\'t use ES6 promise with mpromise style constructor');
}

ES6Promise.use = function(Promise) {
  ES6Promise.ES6 = Promise;
};

module.exports = ES6Promise;

15.2. schema.js

源码:schema.js

15.3. Schema#add(obj, prefix)

Adds key path / schema type pairs to this schema.

参数:
示例:
var ToySchema = new Schema;
ToySchema.add({ name: 'string', color: 'string', price: 'number' });
源码
Schema.prototype.add = function add(obj, prefix) {
  prefix = prefix || '';
  var keys = Object.keys(obj);

  for (var i = 0; i < keys.length; ++i) {
    var key = keys[i];

    if (obj[key] == null) {
      throw new TypeError('Invalid value for schema path `' + prefix + key + '`');
    }

    if (Array.isArray(obj[key]) && obj[key].length === 1 && obj[key][0] == null) {
      throw new TypeError('Invalid value for schema Array path `' + prefix + key + '`');
    }

    if (utils.isObject(obj[key]) &&
        (!obj[key].constructor || utils.getFunctionName(obj[key].constructor) === 'Object') &&
        (!obj[key][this.options.typeKey] || (this.options.typeKey === 'type' && obj[key].type.type))) {
      if (Object.keys(obj[key]).length) {
        // nested object { last: { name: String }}
        this.nested[prefix + key] = true;
        this.add(obj[key], prefix + key + '.');
      } else {
        if (prefix) {
          this.nested[prefix.substr(0, prefix.length - 1)] = true;
        }
        this.path(prefix + key, obj[key]); // mixed type
      }
    } else {
      if (prefix) {
        this.nested[prefix.substr(0, prefix.length - 1)] = true;
      }
      this.path(prefix + key, obj[key]);
    }
  }
};

15.4. Schema#clone()

Returns a deep copy of the schema

返回值:
  • the cloned schema
源码
Schema.prototype.clone = function() {
  var s = new Schema(this.paths, this.options);
  // Clone the call queue
  var cloneOpts = { retainKeyOrder: true };
  s.callQueue = this.callQueue.map(function(f) { return f; });
  s.methods = utils.clone(this.methods, cloneOpts);
  s.statics = utils.clone(this.statics, cloneOpts);
  s.query = utils.clone(this.query, cloneOpts);
  s.plugins = Array.prototype.slice.call(this.plugins);
  s._indexes = utils.clone(this._indexes, cloneOpts);
  s.s.hooks = this.s.hooks.clone();
  return s;
};

15.5. Schema#eachPath(fn)

Iterates the schemas paths similar to Array#forEach.

参数:
返回值:
  • this The callback is passed the pathname and schemaType as arguments on each iteration.
源码
Schema.prototype.eachPath = function(fn) {
  var keys = Object.keys(this.paths),
      len = keys.length;

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

  return this;
};

15.6. Schema#get(key)

Gets a schema option.

参数:
源码
Schema.prototype.get = function(key) {
  return this.options[key];
};

15.7. Schema#index(fields, [options], [options.expires=null])

为当前模式定一个索引(most likely compound)。

参数:
  • fields <Object>

  • [options] <Object> 传递给 MongoDB 驱动器的 createIndex() 函数的选项。

  • [options.expires=null] <String> Mongoose 特有的语法糖,为上面的链接中的 expireAfterSeconds 使用 msexpires 选项转换成秒。

示例:
schema.index({ first: 1, last: -1 })
源码
Schema.prototype.index = function(fields, options) {
  options || (options = {});

  if (options.expires) {
    utils.expires(options);
  }

  this._indexes.push([fields, options]);
  return this;
};

15.8. Schema#indexes()

从字段和模式级索引编译索引

源码
```
<!--endsec-->


## Schema#loadClass(model)

Loads an ES6 class into a schema. Maps setters + getters, static methods, and instance methods to schema virtuals, statics, and methods.

##### 参数:
model &lt;[Function][]&gt;
<!--sec data-title="源码" data-id="sec_Schema_loadClass" data-show=true data-collapse=true ces-->
```js
Schema.prototype.indexes = function() {
  'use strict';

  var indexes = [];
  var schemaStack = [];

  var collectIndexes = function(schema, prefix) {
    // Ignore infinitely nested schemas, if we've already seen this schema
    // along this path there must be a cycle
    if (schemaStack.indexOf(schema) !== -1) {
      return;
    }
    schemaStack.push(schema);

    prefix = prefix || '';
    var key, path, index, field, isObject, options, type;
    var keys = Object.keys(schema.paths);

    for (var i = 0; i < keys.length; ++i) {
      key = keys[i];
      path = schema.paths[key];

      if ((path instanceof MongooseTypes.DocumentArray) || path.$isSingleNested) {
        if (path.options.excludeIndexes !== true) {
          collectIndexes(path.schema, prefix + key + '.');
        }
      } else {
        index = path._index || (path.caster && path.caster._index);

        if (index !== false && index !== null && index !== undefined) {
          field = {};
          isObject = utils.isObject(index);
          options = isObject ? index : {};
          type = typeof index === 'string' ? index :
              isObject ? index.type :
                  false;

          if (type && ~Schema.indexTypes.indexOf(type)) {
            field[prefix + key] = type;
          } else if (options.text) {
            field[prefix + key] = 'text';
            delete options.text;
          } else {
            field[prefix + key] = 1;
          }

          delete options.type;
          if (!('background' in options)) {
            options.background = true;
          }

          indexes.push([field, options]);
        }
      }
    }

    schemaStack.pop();

    if (prefix) {
      fixSubIndexPaths(schema, prefix);
    } else {
      schema._indexes.forEach(function(index) {
        if (!('background' in index[1])) {
          index[1].background = true;
        }
      });
      indexes = indexes.concat(schema._indexes);
    }
  };

  collectIndexes(this);
  return indexes;
}

15.9. Schema#method(method, [fn])

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

参数:
示例:
var schema = kittySchema = new Schema(..);

schema.method('meow', function () {
  console.log('meeeeeoooooooooooow');
})

var Kitty = mongoose.model('Kitty', schema);

var fizz = new Kitty;
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.

schema.method({
    purr: function () {}
  , scratch: function () {}
});

// later
fizz.purr();
fizz.scratch();
源码
Schema.prototype.method = function(name, fn) {
  if (typeof name !== 'string') {
    for (var i in name) {
      this.methods[i] = name[i];
    }
  } else {
    this.methods[name] = fn;
  }
  return this;
};

15.10. Schema#path(path, constructor)

获取/设置 schema 路径。

参数:

设置路径 (如果有两个参数) 获取路径 (如果有一个参数)

示例:
schema.path('name') // 返回一个 SchemaType
schema.path('name', Number) // 将 name` 的 schemaType 改变为 Number
源码
Schema.prototype.path = function(path, obj) {
  if (obj === undefined) {
    if (this.paths[path]) {
      return this.paths[path];
    }
    if (this.subpaths[path]) {
      return this.subpaths[path];
    }
    if (this.singleNestedPaths[path]) {
      return this.singleNestedPaths[path];
    }

    // subpaths?
    return /\.\d+\.?.*$/.test(path)
        ? getPositionalPath(this, path)
        : undefined;
  }

  // some path names conflict with document methods
  if (reserved[path]) {
    throw new Error('`' + path + '` may not be used as a schema pathname');
  }

  if (warnings[path]) {
    console.log('WARN: ' + warnings[path]);
  }

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

  subpaths.forEach(function(sub, i) {
    if (!branch[sub]) {
      branch[sub] = {};
    }
    if (typeof branch[sub] !== 'object') {
      var msg = 'Cannot set nested path `' + path + '`. '
          + 'Parent path `'
          + subpaths.slice(0, i).concat([sub]).join('.')
          + '` already set to type ' + branch[sub].name
          + '.';
      throw new Error(msg);
    }
    branch = branch[sub];
  });

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

  this.paths[path] = Schema.interpretAsType(path, obj, this.options);

  if (this.paths[path].$isSingleNested) {
    for (var key in this.paths[path].schema.paths) {
      this.singleNestedPaths[path + '.' + key] =
          this.paths[path].schema.paths[key];
    }
    for (key in this.paths[path].schema.singleNestedPaths) {
      this.singleNestedPaths[path + '.' + key] =
          this.paths[path].schema.singleNestedPaths[key];
    }

    this.childSchemas.push({
      schema: this.paths[path].schema,
      model: this.paths[path].caster
    });
  } else if (this.paths[path].$isMongooseDocumentArray) {
    this.childSchemas.push({
      schema: this.paths[path].schema,
      model: this.paths[path].casterConstructor
    });
  }
  return this;
};

15.11. Schema#pathType(path)

Returns the pathType of path for this schema.

参数:
返回值:

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

源码
Schema.prototype.pathType = function(path) {
  if (path in this.paths) {
    return 'real';
  }
  if (path in this.virtuals) {
    return 'virtual';
  }
  if (path in this.nested) {
    return 'nested';
  }
  if (path in this.subpaths) {
    return 'real';
  }
  if (path in this.singleNestedPaths) {
    return 'real';
  }

  if (/\.\d+\.|\.\d+$/.test(path)) {
    return getPositionalPathType(this, path);
  }
  return 'adhocOrUndefined';
};

15.12. Schema#plugin(plugin, [opts])

为当前模式注册一个插件。

参数:
参见:
源码
Schema.prototype.plugin = function(fn, opts) {
  if (typeof fn !== 'function') {
    throw new Error('First param to `schema.plugin()` must be a function, ' +
      'got "' + (typeof fn) + '"');
  }

  if (opts &&
      opts.deduplicate) {
    for (var i = 0; i < this.plugins.length; ++i) {
      if (this.plugins[i].fn === fn) {
        return this;
      }
    }
  }
  this.plugins.push({ fn: fn, opts: opts });

  fn(this, opts);
  return this;
};

15.13. Schema#post(method, fn)

为文档定义一个 post 钩子

参数:
参见:
var schema = new Schema(..);
schema.post('save', function (doc) {
  console.log('this fired after a document was saved');
});

schema.post('find', function(docs) {
  console.log('this fired after you run a find query');
});

var Model = mongoose.model('Model', schema);

var m = new Model(..);
m.save(function(err) {
  console.log('this fires after the `post` hook');
});

m.find(function(err, docs) {
  console.log('this fires after the post find hook');
});
源码
Schema.prototype.post = function(method, fn) {
  if (IS_KAREEM_HOOK[method]) {
    this.s.hooks.post.apply(this.s.hooks, arguments);
    return this;
  }
  // assuming that all callbacks with arity < 2 are synchronous post hooks
  if (fn.length < 2) {
    return this.queue('on', [arguments[0], function(doc) {
      return fn.call(doc, doc);
    }]);
  }

  if (fn.length === 3) {
    this.s.hooks.post(method + ':error', fn);
    return this;
  }

  return this.queue('post', [arguments[0], function(next) {
    // wrap original function so that the callback goes last,
    // for compatibility with old code that is using synchronous post hooks
    var _this = this;
    var args = Array.prototype.slice.call(arguments, 1);
    fn.call(this, this, function(err) {
      return next.apply(_this, [err].concat(args));
    });
  }]);
};

15.14. Schema#pre(method, callback)

Defines a pre hook for the document.

参数:
参见:
示例:
var toySchema = new Schema(..);

toySchema.pre('save', function (next) {
  if (!this.created) this.created = new Date;
  next();
})

toySchema.pre('validate', function (next) {
  if (this.name !== 'Woody') this.name = 'Woody';
  next();
})
源码
Schema.prototype.pre = function() {
  var name = arguments[0];
  if (IS_KAREEM_HOOK[name]) {
    this.s.hooks.pre.apply(this.s.hooks, arguments);
    return this;
  }
  return this.queue('pre', arguments);
};

15.15. Schema#queue(name, args)

Adds a method call to the queue.

参数:
  • name <String> name of the document method to call later

  • args <Array> arguments to pass to the method

源码
Schema.prototype.queue = function(name, args) {
  this.callQueue.push([name, args]);
  return this;
};

15.16. Schema#remove(path)

Removes the given path (or [paths]).

参数:
  • path *

    源码
    Schema.prototype.remove = function(path) {
    if (typeof path === 'string') {
    path = [path];
    }
    if (Array.isArray(path)) {
    path.forEach(function(name) {
      if (this.path(name)) {
        delete this.paths[name];
    
        var pieces = name.split('.');
        var last = pieces.pop();
        var branch = this.tree;
        for (var i = 0; i < pieces.length; ++i) {
          branch = branch[pieces[i]];
        }
        delete branch[last];
      }
    }, this);
    }
    };
    

15.17. Schema#requiredPaths(invalidate)

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

参数:
  • invalidate <Boolean> refresh the cache
返回值:
源码
Schema.prototype.requiredPaths = function requiredPaths(invalidate) {
  if (this._requiredpaths && !invalidate) {
    return this._requiredpaths;
  }

  var paths = Object.keys(this.paths),
      i = paths.length,
      ret = [];

  while (i--) {
    var path = paths[i];
    if (this.paths[path].isRequired) {
      ret.push(path);
    }
  }
  this._requiredpaths = ret;
  return this._requiredpaths;
};

15.18. Schema(definition, [options])

Schema constructor.

参数:
继承:
事件:
  • init: Emitted after the schema is compiled into a Model.
示例:
var child = new Schema({ name: String });
var schema = new Schema({ name: String, age: Number, children: [child] });
var Tree = mongoose.model('Tree', schema);

// setting schema options
new Schema({ name: String }, { _id: false, autoIndex: false })
选项:

[minimize]:

注意:

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

源码
function Schema(obj, options) {
  if (!(this instanceof Schema)) {
    return new Schema(obj, options);
  }

  this.obj = obj;
  this.paths = {};
  this.aliases = {};
  this.subpaths = {};
  this.virtuals = {};
  this.singleNestedPaths = {};
  this.nested = {};
  this.inherits = {};
  this.callQueue = [];
  this._indexes = [];
  this.methods = {};
  this.statics = {};
  this.tree = {};
  this.query = {};
  this.childSchemas = [];
  this.plugins = [];

  this.s = {
    hooks: new Kareem(),
    kareemHooks: IS_KAREEM_HOOK
  };

  this.options = this.defaultOptions(options);

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

  // check if _id's value is a subdocument (gh-2276)
  var _idSubDoc = obj && obj._id && utils.isObject(obj._id);

  // ensure the documents get an auto _id unless disabled
  var auto_id = !this.paths['_id'] &&
      (!this.options.noId && this.options._id) && !_idSubDoc;

  if (auto_id) {
    var _obj = {_id: {auto: true}};
    _obj._id[this.options.typeKey] = Schema.ObjectId;
    this.add(_obj);
  }

  for (var i = 0; i < this._defaultMiddleware.length; ++i) {
    var m = this._defaultMiddleware[i];
    this[m.kind](m.hook, !!m.isAsync, m.fn);
  }

  if (this.options.timestamps) {
    this.setupTimestamp(this.options.timestamps);
  }

  // Assign virtual properties based on alias option
  aliasFields(this);
}

15.19. Schema#set(key, [value])

Sets/gets a schema option.

参数:
  • key <String> option name

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

参见:
示例:
schema.set('strict'); // 'true' by default
schema.set('strict', false); // Sets 'strict' to false
schema.set('strict'); // 'false'
源码
Schema.prototype.set = function(key, value, _tags) {
  if (arguments.length === 1) {
    return this.options[key];
  }

  switch (key) {
    case 'read':
      this.options[key] = readPref(value, _tags);
      break;
    case 'safe':
      this.options[key] = value === false
          ? {w: 0}
          : value;
      break;
    case 'timestamps':
      this.setupTimestamp(value);
      this.options[key] = value;
      break;
    default:
      this.options[key] = value;
  }

  return this;
};

15.20. Schema#static(name, [fn])

添加静态的“类”方法到从这个模式编译成的模型中。

参数:
示例:
var schema = new Schema(..);
schema.static('findByName', function (name, callback) {
  return this.find({ name: name }, callback);
});

var Drink = mongoose.model('Drink', schema);
Drink.findByName('sanpellegrino', function (err, drinks) {
  //
});

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

源码
Schema.prototype.static = function(name, fn) {
  if (typeof name !== 'string') {
    for (var i in name) {
      this.statics[i] = name[i];
    }
  } else {
    this.statics[name] = fn;
  }
  return this;
};

15.21. Schema#virtual(name, [options])

使用给定的 name 创建一个虚拟类型

参数:
返回值:
源码
Schema.prototype.virtual = function(name, options) {
  if (options && options.ref) {
    if (!options.localField) {
      throw new Error('Reference virtuals require `localField` option');
    }

    if (!options.foreignField) {
      throw new Error('Reference virtuals require `foreignField` option');
    }

    this.pre('init', function(next, obj) {
      if (mpath.has(name, obj)) {
        var _v = mpath.get(name, obj);
        if (!this.$$populatedVirtuals) {
          this.$$populatedVirtuals = {};
        }

        if (options.justOne) {
          this.$$populatedVirtuals[name] = Array.isArray(_v) ?
            _v[0] :
            _v;
        } else {
          this.$$populatedVirtuals[name] = Array.isArray(_v) ?
            _v :
            _v == null ? [] : [_v];
        }

        mpath.unset(name, obj);
      }
      if (this.ownerDocument) {
        next();
        return this;
      } else {
        next();
      }
    });

    var virtual = this.virtual(name);
    virtual.options = options;
    return virtual.
      get(function() {
        if (!this.$$populatedVirtuals) {
          this.$$populatedVirtuals = {};
        }
        if (name in this.$$populatedVirtuals) {
          return this.$$populatedVirtuals[name];
        }
        return null;
      }).
      set(function(_v) {
        if (!this.$$populatedVirtuals) {
          this.$$populatedVirtuals = {};
        }

        if (options.justOne) {
          this.$$populatedVirtuals[name] = Array.isArray(_v) ?
            _v[0] :
            _v;

          if (typeof this.$$populatedVirtuals[name] !== 'object') {
            this.$$populatedVirtuals[name] = null;
          }
        } else {
          this.$$populatedVirtuals[name] = Array.isArray(_v) ?
            _v :
            _v == null ? [] : [_v];

          this.$$populatedVirtuals[name] = this.$$populatedVirtuals[name].filter(function(doc) {
            return doc && typeof doc === 'object';
          });
        }
      });
  }

  var virtuals = this.virtuals;
  var parts = name.split('.');

  if (this.pathType(name) === 'real') {
    throw new Error('Virtual path "' + name + '"' +
      ' conflicts with a real path in the schema');
  }

  virtuals[name] = parts.reduce(function(mem, part, i) {
    mem[part] || (mem[part] = (i === parts.length - 1)
        ? new VirtualType(options, name)
        : {});
    return mem[part];
  }, this.tree);

  return virtuals[name];
};

15.22. Schema#virtualpath(name)

Returns the virtual type with the given name.

参数:
返回值:
源码
Schema.prototype.virtualpath = function(name) {
  return this.virtuals[name];
};

15.23. Schema.indexTypes()

The allowed index types

源码
var indexTypes = '2d 2dsphere hashed text'.split(' ');

Object.defineProperty(Schema, 'indexTypes', {
  get: function() {
    return indexTypes;
  },
  set: function() {
    throw new Error('Cannot overwrite Schema.indexTypes');
  }
});

15.24. Schema.reserved

Reserved document keys.

源码
Schema.reserved = Object.create(null);
var reserved = Schema.reserved;
// Core object
reserved['prototype'] =
// EventEmitter
reserved.emit =
reserved.on =
reserved.once =
reserved.listeners =
reserved.removeListener =
// document properties and functions
reserved.collection =
reserved.db =
reserved.errors =
reserved.init =
reserved.isModified =
reserved.isNew =
reserved.get =
reserved.modelName =
reserved.save =
reserved.schema =
reserved.toObject =
reserved.validate =
reserved.remove =
// hooks.js
reserved._pres = reserved._posts = 1;

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.

on, emit, _events, db, get, set, init, isNew, errors, schema, options, modelName, collection, _pres, _posts, toObject
注意:

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.

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

15.25. Schema.Types

The various built-in Mongoose Schema Types.

源码
Schema.Types = MongooseTypes = require('./schema/index');
示例:
var mongoose = require('mongoose');
var ObjectId = mongoose.Schema.Types.ObjectId;
类型:

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

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

15.26. Schema#childSchemas

Array of child schemas (from document arrays and single nested subdocs) and their corresponding compiled models. Each element of the array is an object with 2 properties: schema and model.

This property is typically only useful for plugin authors and advanced users. You do not need to interact with this property at all to use mongoose.

源码
Object.defineProperty(Schema.prototype, 'childSchemas', {
  configurable: false,
  enumerable: true,
  writable: true
});

15.27. Schema#obj

The original object passed to the schema constructor

示例:
var schema = new Schema({ a: String }).add({ b: String });
schema.obj; // { a: String }
源码
Schema.prototype.obj;

16. document.js

源码:document.js

16.1. MISSING method name

Getter/setter, determines whether the document was removed or not.

参数:
  • [val] <Boolean> optional, overrides whether mongoose thinks the doc is deleted
返回值:
  • <Boolean> whether mongoose thinks this doc is deleted.
示例:
product.remove(function (err, product) {
  product.isDeleted(); // true
  product.remove(); // no-op, doesn't send anything to the db

  product.isDeleted(false);
  product.isDeleted(); // false
  product.remove(); // will execute a remove against the db
})
源码
Document.prototype.$isDeleted = function(val) {
  if (arguments.length === 0) {
    return !!this.$__.isDeleted;
  }

  this.$__.isDeleted = !!val;
  return this;
};

16.2. MISSING method name

Alias for set(), used internally to avoid conflicts

参数:
  • path path or object of key/vals to set

  • val <Any> the value to set

  • [type] optionally specify a type for "on-the-fly" attributes

  • [options] <Object> optionally specify options that modify the behavior of the set

源码
Document.prototype.$set = function(path, val, type, options) {
  if (type && utils.getFunctionName(type.constructor) === 'Object') {
    options = type;
    type = undefined;
  }

  options = options || {};
  var merge = options.merge;
  var adhoc = type && type !== true;
  var constructing = type === true;
  var adhocs;

  var strict = 'strict' in options
      ? options.strict
      : this.$__.strictMode;

  if (adhoc) {
    adhocs = this.$__.adhocPaths || (this.$__.adhocPaths = {});
    adhocs[path] = Schema.interpretAsType(path, type, this.schema.options);
  }

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

    if (path === null || path === void 0) {
      var _ = path;
      path = val;
      val = _;
    } else {
      var prefix = val
          ? val + '.'
          : '';

      if (path instanceof Document) {
        if (path.$__isNested) {
          path = path.toObject();
        } else {
          path = path._doc;
        }
      }

      var keys = Object.keys(path);
      var len = keys.length;
      var i = 0;
      var pathtype;
      var key;

      if (len === 0 && !this.schema.options.minimize) {
        if (val) {
          this.$set(val, {});
        }
        return this;
      }

      if (this.schema.options.retainKeyOrder) {
        while (i < len) {
          _handleIndex.call(this, i++);
        }
      } else {
        while (len--) {
          _handleIndex.call(this, len);
        }
      }

      return this;
    }
  }

  function _handleIndex(i) {
    key = keys[i];
    var pathName = prefix + key;
    pathtype = this.schema.pathType(pathName);

    if (path[key] !== null
        && path[key] !== void 0
          // need to know if plain object - no Buffer, ObjectId, ref, etc
        && utils.isObject(path[key])
        && (!path[key].constructor || utils.getFunctionName(path[key].constructor) === 'Object')
        && pathtype !== 'virtual'
        && pathtype !== 'real'
        && !(this.$__path(pathName) instanceof MixedSchema)
        && !(this.schema.paths[pathName] &&
        this.schema.paths[pathName].options &&
        this.schema.paths[pathName].options.ref)) {
      this.$set(path[key], prefix + key, constructing);
    } else if (strict) {
      // Don't overwrite defaults with undefined keys (gh-3981)
      if (constructing && path[key] === void 0 &&
          this.get(key) !== void 0) {
        return;
      }

      if (pathtype === 'real' || pathtype === 'virtual') {
        // Check for setting single embedded schema to document (gh-3535)
        var p = path[key];
        if (this.schema.paths[pathName] &&
            this.schema.paths[pathName].$isSingleNested &&
            path[key] instanceof Document) {
          p = p.toObject({ virtuals: false, transform: false });
        }
        this.$set(prefix + key, p, constructing);
      } else if (pathtype === 'nested' && path[key] instanceof Document) {
        this.$set(prefix + key,
            path[key].toObject({transform: false}), constructing);
      } else if (strict === 'throw') {
        if (pathtype === 'nested') {
          throw new ObjectExpectedError(key, path[key]);
        } else {
          throw new StrictModeError(key);
        }
      }
    } else if (path[key] !== void 0) {
      this.$set(prefix + key, path[key], constructing);
    }
  }

  var pathType = this.schema.pathType(path);
  if (pathType === 'nested' && val) {
    if (utils.isObject(val) &&
        (!val.constructor || utils.getFunctionName(val.constructor) === 'Object')) {
      if (!merge) {
        this.setValue(path, null);
        cleanModifiedSubpaths(this, path);
      }

      if (Object.keys(val).length === 0) {
        this.setValue(path, {});
        this.markModified(path);
        cleanModifiedSubpaths(this, path);
      } else {
        this.$set(val, path, constructing);
      }
      return this;
    }
    this.invalidate(path, new MongooseError.CastError('Object', val, path));
    return this;
  }

  var schema;
  var parts = path.split('.');

  if (pathType === 'adhocOrUndefined' && strict) {
    // check for roots that are Mixed types
    var mixed;

    for (i = 0; i < parts.length; ++i) {
      var subpath = parts.slice(0, i + 1).join('.');
      schema = this.schema.path(subpath);
      if (schema instanceof MixedSchema) {
        // allow changes to sub paths of mixed types
        mixed = true;
        break;
      }

      // If path is underneath a virtual, bypass everything and just set it.
      if (i + 1 < parts.length && this.schema.pathType(subpath) === 'virtual') {
        mpath.set(path, val, this);
        return this;
      }
    }

    if (!mixed) {
      if (strict === 'throw') {
        throw new StrictModeError(path);
      }
      return this;
    }
  } else if (pathType === 'virtual') {
    schema = this.schema.virtualpath(path);
    schema.applySetters(val, this);
    return this;
  } else {
    schema = this.$__path(path);
  }

  // gh-4578, if setting a deeply nested path that doesn't exist yet, create it
  var cur = this._doc;
  var curPath = '';
  for (i = 0; i < parts.length - 1; ++i) {
    cur = cur[parts[i]];
    curPath += (curPath.length > 0 ? '.' : '') + parts[i];
    if (!cur) {
      this.$set(curPath, {});
      // Hack re: gh-5800. If nested field is not selected, it probably exists
      // so `MongoError: cannot use the part (nested of nested.num) to
      // traverse the element ({nested: null})` is not likely. If user gets
      // that error, its their fault for now. We should reconsider disallowing
      // modifying not selected paths for v5.
      if (!this.isSelected(curPath)) {
        this.unmarkModified(curPath);
      }
      cur = this.getValue(curPath);
    }
  }

  var pathToMark;

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

  if (parts.length <= 1) {
    pathToMark = path;
  } else {
    for (i = 0; i < parts.length; ++i) {
      subpath = parts.slice(0, i + 1).join('.');
      if (this.isDirectModified(subpath) // earlier prefixes that are already
            // marked as dirty have precedence
          || this.get(subpath) === null) {
        pathToMark = subpath;
        break;
      }
    }

    if (!pathToMark) {
      pathToMark = path;
    }
  }

  // if this doc is being constructed we should not trigger getters
  var priorVal = constructing ?
    undefined :
    this.getValue(path);

  if (!schema) {
    this.$__set(pathToMark, path, constructing, parts, schema, val, priorVal);
    return this;
  }

  var shouldSet = true;
  try {
    // If the user is trying to set a ref path to a document with
    // the correct model name, treat it as populated
    var didPopulate = false;
    if (schema.options &&
        schema.options.ref &&
        val instanceof Document &&
        (schema.options.ref === val.constructor.modelName || schema.options.ref === val.constructor.baseModelName)) {
      if (this.ownerDocument) {
        this.ownerDocument().populated(this.$__fullPath(path),
          val._id, {model: val.constructor});
      } else {
        this.populated(path, val._id, {model: val.constructor});
      }
      didPopulate = true;
    }

    var popOpts;
    if (schema.options &&
        Array.isArray(schema.options[this.schema.options.typeKey]) &&
        schema.options[this.schema.options.typeKey].length &&
        schema.options[this.schema.options.typeKey][0].ref &&
        Array.isArray(val) &&
        val.length > 0 &&
        val[0] instanceof Document &&
        val[0].constructor.modelName &&
        (schema.options[this.schema.options.typeKey][0].ref === val[0].constructor.baseModelName || schema.options[this.schema.options.typeKey][0].ref === val[0].constructor.modelName)) {
      if (this.ownerDocument) {
        popOpts = { model: val[0].constructor };
        this.ownerDocument().populated(this.$__fullPath(path),
          val.map(function(v) { return v._id; }), popOpts);
      } else {
        popOpts = { model: val[0].constructor };
        this.populated(path, val.map(function(v) { return v._id; }), popOpts);
      }
      didPopulate = true;
    }

    var setterContext = constructing && this.$__.$options.priorDoc ?
      this.$__.$options.priorDoc :
      this;
    val = schema.applySetters(val, setterContext, false, priorVal);

    if (!didPopulate && this.$__.populated) {
      delete this.$__.populated[path];
    }

    this.$markValid(path);
  } catch (e) {
    this.invalidate(path,
      new MongooseError.CastError(schema.instance, val, path, e));
    shouldSet = false;
  }

  if (shouldSet) {
    this.$__set(pathToMark, path, constructing, parts, schema, val, priorVal);
  }

  if (schema.$isSingleNested && (this.isDirectModified(path) || val == null)) {
    cleanModifiedSubpaths(this, path);
  }

  return this;
};

16.3. Document#$ignore(path)

Don't run validation on this path or persist changes to this path.

参数:
  • path <String> the path to ignore
示例:
doc.foo = null;
doc.$ignore('foo');
doc.save() // changes to foo will not be persisted and validators won't be run

16.4. Document#$isDefault([path])

Checks if a path is set to its default.

参数:
返回值:
示例:
MyModel = mongoose.model('test', { name: { type: String, default: 'Val '} });
var m = new MyModel();
m.$isDefault('name'); // true

16.5. Document#depopulate(path)

Takes a populated field and returns it to its unpopulated state.

参数:
返回值:
参见:
示例:
Model.findOne().populate('author').exec(function (err, doc) {
  console.log(doc.author.name); // Dr.Seuss
  console.log(doc.depopulate('author'));
  console.log(doc.author); // '5144cf8050f071d979c118a7'
})

If the path was not populated, this is a no-op.

源码
Document.prototype.depopulate = function(path) {
  if (typeof path === 'string') {
    path = path.split(' ');
  }
  for (var i = 0; i < path.length; i++) {
    var populatedIds = this.populated(path[i]);
    if (!populatedIds) {
      continue;
    }
    delete this.$__.populated[path[i]];
    this.$set(path[i], populatedIds);
  }
  return this;
};

16.6. Document#equals(doc)

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

参数:
返回值:

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().

源码
Document.prototype.equals = function(doc) {
  if (!doc) {
    return false;
  }

  var tid = this.get('_id');
  var docid = doc.get ? doc.get('_id') : doc;
  if (!tid && !docid) {
    return deepEqual(this, doc);
  }
  return tid && tid.equals
      ? tid.equals(docid)
      : tid === docid;
};

16.7. Document#execPopulate()

Explicitly executes population and returns a promise. Useful for ES2015 integration.

返回值:
  • <Promise> promise that resolves to the document when population is done
参见:
示例:
var promise = doc.
  populate('company').
  populate({
    path: 'notes',
    match: /airline/,
    select: 'text',
    model: 'modelName'
    options: opts
  }).
  execPopulate();

// summary
doc.execPopulate().then(resolve, reject);
源码
Document.prototype.execPopulate = function() {
  var Promise = PromiseProvider.get();
  var _this = this;
  return new Promise.ES6(function(resolve, reject) {
    _this.populate(function(error, res) {
      if (error) {
        reject(error);
      } else {
        resolve(res);
      }
    });
  });
};

16.8. Document#get(path, [type])

Returns the value of a path.

参数:
  • path <String>

  • [type] optionally specify a type for on-the-fly attributes

示例:
// path
doc.get('age') // 47

// dynamic casting to a string
doc.get('age', String) // "47"
源码
Document.prototype.get = function(path, type) {
  var adhoc;
  if (type) {
    adhoc = Schema.interpretAsType(path, type, this.schema.options);
  }

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

  if (schema instanceof VirtualType) {
    return schema.applyGetters(null, this);
  }

  for (var i = 0, l = pieces.length; i < l; i++) {
    obj = obj === null || obj === void 0
        ? undefined
        : obj[pieces[i]];
  }

  if (adhoc) {
    obj = adhoc.cast(obj);
  }

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

  return obj;
};

16.9. Document#init(doc, fn)

Initializes the document without setters or marking anything modified.

参数:

Called internally after a document is returned from mongodb.

源码
Document.prototype.init = function(doc, opts, fn) {
  // do not prefix this method with $__ since its
  // used by public hooks

  if (typeof opts === 'function') {
    fn = opts;
    opts = null;
  }

  this.isNew = false;
  this.$init = true;

  // handle docs with populated paths
  // If doc._id is not null or undefined
  if (doc._id !== null && doc._id !== undefined &&
    opts && opts.populated && opts.populated.length) {
    var id = String(doc._id);
    for (var i = 0; i < opts.populated.length; ++i) {
      var item = opts.populated[i];
      if (item.isVirtual) {
        this.populated(item.path, utils.getValue(item.path, doc), item);
      } else {
        this.populated(item.path, item._docs[id], item);
      }
    }
  }

  init(this, doc, this._doc);

  this.emit('init', this);
  this.constructor.emit('init', this);

  this.$__._id = this._id;

  if (fn) {
    fn(null);
  }
  return this;
};

16.10. Document#inspect()

Helper for console.log

源码
Document.prototype.inspect = function(options) {
  var isPOJO = options &&
    utils.getFunctionName(options.constructor) === 'Object';
  var opts;
  if (isPOJO) {
    opts = options;
    opts.minimize = false;
    opts.retainKeyOrder = true;
  }
  return this.toObject(opts);
};

16.11. Document#invalidate(path, errorMsg, value, [kind])

Marks a path as invalid, causing validation to fail.

参数:
  • path <String> the field to invalidate

  • errorMsg the error which states the reason path was invalid

  • value optional invalid value

  • [kind] <String> optional kind property for the error

返回值:
  • the current ValidationError, with all currently invalidated paths The errorMsg argument will become the message of the ValidationError.

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

doc.invalidate('size', 'must be less than 20', 14);

doc.validate(function (err) {
  console.log(err)
  // prints
  { message: 'Validation failed',
    name: 'ValidationError',
    errors:
     { size:
        { message: 'must be less than 20',
          name: 'ValidatorError',
          path: 'size',
          type: 'user defined',
          value: 14 } } }
})
源码
Document.prototype.invalidate = function(path, err, val, kind) {
  if (!this.$__.validationError) {
    this.$__.validationError = new ValidationError(this);
  }

  if (this.$__.validationError.errors[path]) {
    return;
  }

  if (!err || typeof err === 'string') {
    err = new ValidatorError({
      path: path,
      message: err,
      type: kind || 'user defined',
      value: val
    });
  }

  if (this.$__.validationError === err) {
    return this.$__.validationError;
  }

  this.$__.validationError.addError(path, err);
  return this.$__.validationError;
};

16.12. Document#isDirectModified(path)

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

参数:
返回值:
示例:
doc.set('documents.0.title', 'changed');
doc.isDirectModified('documents.0.title') // true
doc.isDirectModified('documents') // false
源码
Document.prototype.isDirectModified = function(path) {
  return (path in this.$__.activePaths.states.modify);
};

16.13. Document#isDirectSelected(path)

Checks if path was explicitly selected. If no projection, always returns true.

参数:
返回值:
示例:
Thing.findOne().select('nested.name').exec(function (err, doc) {
   doc.isDirectSelected('nested.name') // true
   doc.isDirectSelected('nested.otherName') // false
   doc.isDirectSelected('nested')  // false
})
源码
Document.prototype.isDirectSelected = function isDirectSelected(path) {
  if (this.$__.selected) {
    if (path === '_id') {
      return this.$__.selected._id !== 0;
    }

    var paths = Object.keys(this.$__.selected);
    var i = paths.length;
    var inclusive = null;
    var cur;

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

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

    if (inclusive === null) {
      return true;
    }

    if (path in this.$__.selected) {
      return inclusive;
    }

    return !inclusive;
  }

  return true;
};

16.14. Document#isInit(path)

Checks if path was initialized.

参数:
返回值:
源码
Document.prototype.isInit = function(path) {
  return (path in this.$__.activePaths.states.init);
};

16.15. Document#isModified([path])

Returns true if this document was modified, else false.

参数:
返回值:

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

示例:
doc.set('documents.0.title', 'changed');
doc.isModified()                      // true
doc.isModified('documents')           // true
doc.isModified('documents.0.title')   // true
doc.isModified('documents otherProp') // true
doc.isDirectModified('documents')     // false
源码
Document.prototype.isModified = function(paths) {
  if (paths) {
    if (!Array.isArray(paths)) {
      paths = paths.split(' ');
    }
    var modified = this.modifiedPaths();
    var directModifiedPaths = Object.keys(this.$__.activePaths.states.modify);
    var isModifiedChild = paths.some(function(path) {
      return !!~modified.indexOf(path);
    });
    return isModifiedChild || paths.some(function(path) {
      return directModifiedPaths.some(function(mod) {
        return mod === path || path.indexOf(mod + '.') === 0;
      });
    });
  }
  return this.$__.activePaths.some('modify');
};

16.16. Document#isSelected(path)

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

参数:
返回值:
示例:
Thing.findOne().select('name').exec(function (err, doc) {
   doc.isSelected('name') // true
   doc.isSelected('age')  // false
})
源码
Document.prototype.isSelected = function isSelected(path) {
  if (this.$__.selected) {
    if (path === '_id') {
      return this.$__.selected._id !== 0;
    }

    var paths = Object.keys(this.$__.selected);
    var i = paths.length;
    var inclusive = null;
    var cur;

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

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

    if (inclusive === null) {
      return true;
    }

    if (path in this.$__.selected) {
      return inclusive;
    }

    i = paths.length;
    var pathDot = path + '.';

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

      if (cur.indexOf(pathDot) === 0) {
        return inclusive || cur !== pathDot;
      }

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

    return !inclusive;
  }

  return true;
};

16.17. Document#markModified(path, [scope])

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

参数:
  • path <String> the path to mark modified

  • [scope] <Document> the scope to run validators with

Very helpful when using Mixed types.

示例:
doc.mixed.type = 'changed';
doc.markModified('mixed.type');
doc.save() // changes to mixed.type are now persisted
源码
Document.prototype.markModified = function(path, scope) {
  this.$__.activePaths.modify(path);
  if (scope != null && !this.ownerDocument) {
    this.$__.pathsToScopes[path] = scope;
  }
};

16.18. Document#modifiedPaths()

Returns the list of paths that have been modified.

返回值:
  • <Array> *
    源码
    Document.prototype.modifiedPaths = function() {
    var directModifiedPaths = Object.keys(this.$__.activePaths.states.modify);
    return directModifiedPaths.reduce(function(list, path) {
    var parts = path.split('.');
    return list.concat(parts.reduce(function(chains, part, i) {
      return chains.concat(parts.slice(0, i).concat(part).join('.'));
    }, []).filter(function(chain) {
      return (list.indexOf(chain) === -1);
    }));
    }, []);
    };
    

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

Populates document references, executing the callback when complete. If you want to use promises instead, use this function with execPopulate()

参数:
  • [path] The path to populate or an options object

  • [callback] <Function> When passed, population is invoked

返回值:
参见:
示例:
doc
.populate('company')
.populate({
  path: 'notes',
  match: /airline/,
  select: 'text',
  model: 'modelName'
  options: opts
}, function (err, user) {
  assert(doc._id === user._id) // the document itself is passed
})

// summary
doc.populate(path)                   // not executed
doc.populate(options);               // not executed
doc.populate(path, callback)         // executed
doc.populate(options, callback);     // executed
doc.populate(callback);              // executed
doc.populate(options).execPopulate() // executed, returns promise
注意:

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

源码
Document.prototype.depopulate = function(path) {
  if (typeof path === 'string') {
    path = path.split(' ');
  }
  for (var i = 0; i < path.length; i++) {
    var populatedIds = this.populated(path[i]);
    if (!populatedIds) {
      continue;
    }
    delete this.$__.populated[path[i]];
    this.$set(path[i], populatedIds);
  }
  return this;
};

16.20. Document#populated(path)

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

参数:
返回值:
示例:
Model.findOne().populate('author').exec(function (err, doc) {
  console.log(doc.author.name)         // Dr.Seuss
  console.log(doc.populated('author')) // '5144cf8050f071d979c118a7'
})

If the path was not populated, undefined is returned.

源码
Document.prototype.populated = function(path, val, options) {
  // val and options are internal

  if (val === null || val === void 0) {
    if (!this.$__.populated) {
      return undefined;
    }
    var v = this.$__.populated[path];
    if (v) {
      return v.value;
    }
    return undefined;
  }

  // internal

  if (val === true) {
    if (!this.$__.populated) {
      return undefined;
    }
    return this.$__.populated[path];
  }

  this.$__.populated || (this.$__.populated = {});
  this.$__.populated[path] = {value: val, options: options};
  return val;
};

16.21. function Object() { [native code] }#save([options], [options.safe], [options.validateBeforeSave], [fn])

Saves this document.

参数:
  • [options] <Object> options optional options

  • [options.safe] <Object> overrides schema's safe option

  • [options.validateBeforeSave] <Boolean> set to false to save without validating.

  • [fn] <Function> optional callback

返回值:
参见:
示例:
product.sold = Date.now();
product.save(function (err, product, numAffected) {
  if (err) ..
})

* The callback will receive three parameters

  • err if an error occurred
  • product which is the saved product
  • numAffected will be 1 when the document was successfully persisted to MongoDB, otherwise 0. Unless you tweak mongoose's internals, you don't need to worry about checking this parameter for errors - checking err is sufficient to make sure your document was properly saved.

As an extra measure of flow control, save will return a Promise.

示例:
product.save().then(function(product) {
   ...
});

For legacy reasons, mongoose stores object keys in reverse order on initial save. That is, { a: 1, b: 2 } will be saved as { b: 2, a: 1 } in MongoDB. To override this behavior, set the toObject.retainKeyOrder option to true on your schema.

16.22. (path, val, [type], [options])

Sets the value of a path, or many paths.

参数:
  • path path or object of key/vals to set

  • val <Any> the value to set

  • [type] optionally specify a type for "on-the-fly" attributes

  • [options] <Object> optionally specify options that modify the behavior of the set

示例:
// path, value
doc.set(path, value)

// object
doc.set({
    path  : value
  , path2 : {
       path  : value
    }
})

// on-the-fly cast to number
doc.set(path, value, Number)

// on-the-fly cast to string
doc.set(path, value, String)

// changing strict mode behavior
doc.set(path, value, { strict: false });
源码
Document.prototype.set = Document.prototype.$set;

16.23. Document#toJSON(options)

The return value of this method is used in calls to JSON.stringify(doc).

参数:
返回值:
参见:

This method accepts the same options as Document#toObject. To apply the options to every document of your schema by default, set your schemas toJSON option to the same argument.

schema.set('toJSON', { virtuals: true })

See schema options for details.

源码
Document.prototype.toJSON = function(options) {
  return this.$toObject(options, true);
};

16.24. Document#toObject([options])

Converts this document into a plain javascript object, ready for storage in MongoDB.

参数:
返回值:
参见:

Buffers are converted to instances of mongodb.Binary for proper storage.

选项:
  • getters apply all getters (path and virtual getters)
  • virtuals apply virtual getters (can override getters option)
  • minimize remove empty objects (defaults to true)
  • transform a transform function to apply to the resulting document before returning
  • depopulate depopulate any populated paths, replacing them with their original refs (defaults to false)
  • versionKey whether to include the version key (defaults to true)
  • retainKeyOrder keep the order of object keys. If this is set to true, Object.keys(new Doc({ a: 1, b: 2}).toObject()) will always produce ['a', 'b'] (defaults to false)
Getters/Virtuals

Example of only applying path getters

doc.toObject({ getters: true, virtuals: false })

Example of only applying virtual getters

doc.toObject({ virtuals: true })

Example of applying both path and virtual getters

doc.toObject({ getters: true })

To apply these options to every document of your schema by default, set your schemas toObject option to the same argument.

schema.set('toObject', { virtuals: true })
Transform

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.

Transform functions receive three arguments

function (doc, ret, options) {}
  • doc The mongoose document which is being converted
  • ret The plain object representation which has been converted
  • options The options in use (either schema options or the options passed inline)
示例:
// specify the transform schema option
if (!schema.options.toObject) schema.options.toObject = {};
schema.options.toObject.transform = function (doc, ret, options) {
  // remove the _id of every document before returning the result
  delete ret._id;
  return ret;
}

// without the transformation in the schema
doc.toObject(); // { _id: 'anId', name: 'Wreck-it Ralph' }

// with the transformation
doc.toObject(); // { name: 'Wreck-it Ralph' }

With transformations we can do a lot more than remove properties. We can even return completely new customized objects:

if (!schema.options.toObject) schema.options.toObject = {};
schema.options.toObject.transform = function (doc, ret, options) {
  return { movie: ret.name }
}

// without the transformation in the schema
doc.toObject(); // { _id: 'anId', name: 'Wreck-it Ralph' }

// with the transformation
doc.toObject(); // { movie: 'Wreck-it Ralph' }
注意:

if a transform function returns undefined, the return value will be ignored.

Transformations may also be applied inline, overridding any transform set in the options:

function xform (doc, ret, options) {
  return { inline: ret.name, custom: true }
}

// pass the transform as an inline option
doc.toObject({ transform: xform }); // { inline: 'Wreck-it Ralph', custom: true }

If you want to skip transformations, use transform: false:

if (!schema.options.toObject) schema.options.toObject = {};
schema.options.toObject.hide = '_id';
schema.options.toObject.transform = function (doc, ret, options) {
  if (options.hide) {
    options.hide.split(' ').forEach(function (prop) {
      delete ret[prop];
    });
  }
  return ret;
}

var doc = new Doc({ _id: 'anId', secret: 47, name: 'Wreck-it Ralph' });
doc.toObject();                                        // { secret: 47, name: 'Wreck-it Ralph' }
doc.toObject({ hide: 'secret _id', transform: false });// { _id: 'anId', secret: 47, name: 'Wreck-it Ralph' }
doc.toObject({ hide: 'secret _id', transform: true }); // { name: 'Wreck-it Ralph' }

Transforms are applied only to the document and are not applied to sub-documents.

Transforms, like all of these options, are also available for toJSON.

See schema options for some more details.

During save, no custom options are applied to the document before being sent to the database.

源码
Document.prototype.toObject = function(options) {
  return this.$toObject(options);
};

16.25. Document#toString()

Helper for console.log

16.26. Document#unmarkModified(path)

Clears the modified state on the specified path.

参数:
  • path <String> the path to unmark modified
示例:
doc.foo = 'bar';
doc.unmarkModified('foo');
doc.save() // changes to foo will not be persisted
源码
Document.prototype.unmarkModified = function(path) {
  this.$__.activePaths.init(path);
  delete this.$__.pathsToScopes[path];
};

16.27. Document#update(doc, options, callback)

Sends an update command with this document _id as the query selector.

参数:
返回值:
参见:
示例:
weirdCar.update({$inc: {wheels:1}}, { w: 1 }, callback);
Valid options:
same as in Model.update
源码
Document.prototype.update = function update() {
  var args = utils.args(arguments);
  args.unshift({_id: this._id});
  return this.constructor.update.apply(this.constructor, args);
};

16.28. Document#validate(optional, callback)

Executes registered validation rules for this document.

参数:
  • optional <Object> options internal options

  • callback <Function> optional callback called after validation completes, passing an error if one occurred

返回值:
注意:

This method is called pre save and if a validation rule is violated, save is aborted and the error is returned to your callback.

示例:
doc.validate(function (err) {
  if (err) handleError(err);
  else // validation passed
});
源码
Document.prototype.validate = function(options, callback) {
  if (typeof options === 'function') {
    callback = options;
    options = null;
  }

  this.$__validate(callback || function() {});
};

16.29. Document#validateSync(pathsToValidate)

Executes registered validation rules (skipping asynchronous validators) for this document.

参数:
  • pathsToValidate <Array, string> only validate the given paths
返回值:
  • MongooseError if there are errors during validation, or undefined if there is no error.
注意:

This method is useful if you need synchronous validation.

示例:
var err = doc.validateSync();
if ( err ){
  handleError( err );
} else {
  // validation passed
}
源码
Document.prototype.validateSync = function(pathsToValidate) {
  var _this = this;

  if (typeof pathsToValidate === 'string') {
    pathsToValidate = pathsToValidate.split(' ');
  }

  // only validate required fields when necessary
  var paths = _getPathsToValidate(this);

  if (pathsToValidate && pathsToValidate.length) {
    var tmp = [];
    for (var i = 0; i < paths.length; ++i) {
      if (pathsToValidate.indexOf(paths[i]) !== -1) {
        tmp.push(paths[i]);
      }
    }
    paths = tmp;
  }

  var validating = {};

  paths.forEach(function(path) {
    if (validating[path]) {
      return;
    }

    validating[path] = true;

    var p = _this.schema.path(path);
    if (!p) {
      return;
    }
    if (!_this.$isValid(path)) {
      return;
    }

    var val = _this.getValue(path);
    var err = p.doValidateSync(val, _this);
    if (err) {
      _this.invalidate(path, err, undefined, true);
    }
  });

  var err = _this.$__.validationError;
  _this.$__.validationError = undefined;
  _this.emit('validate', _this);
  _this.constructor.emit('validate', _this);

  if (err) {
    for (var key in err.errors) {
      // Make sure cast errors persist
      if (err.errors[key] instanceof MongooseError.CastError) {
        _this.invalidate(key, err.errors[key]);
      }
    }
  }

  return err;
};

16.30. Document.$markValid(path)

Marks a path as valid, removing existing validation errors.

参数:
  • path <String> the field to mark as valid

16.31. Document#errors

Hash containing current validation errors.

源码
Document.prototype.errors;

16.32. Document#id

这个文档 _id 的字符串版本。

注意:

默认情况下,这个 getter 存在于所有文档中。可以在构造时通过设置 Schema 的 id 选项 来禁用该 getter 。 This getter exists on all documents by default. The getter can be disabled by setting the id option of its Schema to false at construction time.

new Schema({ name: String }, { id: false });

源码
Document.prototype.id;
参见:

16.33. Document#isNew

布尔值,标志指定文档是否为新创建。若为新创建,则为 true,否则为 false

源码
Document.prototype.isNew;

16.34. Document#schema

文档的模式。

源码
Document.prototype.schema;

17. query.js

源码:query.js

17.1. Query#$where(js)

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

参数:
返回值:
参见:
示例:
query.$where('this.comments.length === 10 || this.name.length === 5')

// or

query.$where(function () {
  return this.comments.length === 10 || this.name.length === 5;
})
注意:

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.

17.2. Query#all([path], val)

Specifies an $all query condition.

参数:
参见:

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

17.3. Query#and(array)

Specifies arguments for a $and condition.

参数:
  • array <Array> array of conditions
返回值:
参见:
示例:
query.and([{ color: 'green' }, { status: 'ok' }])

17.4. Query#batchSize(val)

Specifies the batchSize option.

参数:
参见:
示例:
query.batchSize(100)
注意:

Cannot be used with distinct()

17.5. Query#box(val, Upper)

Specifies a $box condition

参数:
返回值:
参见:
示例:
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 })

17.6. Query#cast(model, [obj])

Casts this query to the schema of model

参数:
返回值:
注意:

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

源码
Query.prototype.cast = function(model, obj) {
  obj || (obj = this._conditions);

  try {
    return cast(model.schema, obj, {
      upsert: this.options && this.options.upsert,
      strict: (this.options && 'strict' in this.options) ?
        this.options.strict :
        (model.schema.options && model.schema.options.strict),
      strictQuery: (this.options && this.options.strictQuery) ||
        (model.schema.options && model.schema.options.strictQuery)
    }, this);
  } catch (err) {
    // CastError, assign model
    if (typeof err.setModel === 'function') {
      err.setModel(model);
    }
    throw err;
  }
};

17.7. Query#catch([reject])

Executes the query returning a Promise which will be resolved with either the doc(s) or rejected with the error. Like .then(), but only takes a rejection handler.

参数:
返回值:
源码
Query.prototype.catch = function(reject) {
  return this.exec().then(null, reject);
};

17.8. Query#center()

DEPRECATED Alias for circle

Deprecated. Use circle instead.

17.9. Query#centerSphere([path], val)

DEPRECATED Specifies a $centerSphere condition

参数:
* `[path]` &lt;[String][]&gt;

* `val` &lt;[Object][]&gt;
返回值:
* &lt;[Query][]&gt; this
参见:
* http://www.mongodb.org/display/DOCS/Geospatial+Indexing

* [$centerSphere](http://docs.mongodb.org/manual/reference/operator/centerSphere/)

Deprecated. Use circle instead.

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

17.10. Query#circle([path], area)

Specifies a $center or $centerSphere condition.

参数:
返回值:
参见:
示例:
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

17.11. Query#collation(value)

Adds a collation to this op (MongoDB 3.4 and up)

参数:
返回值:
参见:
源码
Query.prototype.collation = function(value) {
  if (this.options == null) {
    this.options = {};
  }
  this.options.collation = value;
  return this;
};

17.12. Query#comment(val)

Specifies the comment option.

参数:
参见:
示例:
query.comment('login query')
注意:

Cannot be used with distinct()

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

Specifying this query as a count query.

参数:
  • [criteria] <Object> mongodb selector

  • [callback] <Function> optional params are (error, count)

返回值:
参见:

Passing a callback executes the query.

该函数触发以下中间件

  • count()
示例:
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);
})
源码
Query.prototype.count = function(conditions, callback) {
  if (typeof conditions === 'function') {
    callback = conditions;
    conditions = undefined;
  }

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

  this.op = 'count';
  if (!callback) {
    return this;
  }

  this._count(callback);

  return this;
};

17.14. Query#cursor([options])

返回一个环绕 mongodb driver cursor 的包装器。 QueryCursor 暴露了一个 Streams3 兼容的接口,以及一个 .next() 函数。

参数:
返回值:
参见:

.cursor() 函数会触发 pre find 钩子, 但不会触发 post find 钩子。

示例:
// 有两种使用 cursor 的方法。首先,作为流(stream):
  find({ name: /^hello/ }).
  cursor().
  on('data', function(doc) { console.log(doc); }).
  on('end', function() { console.log('Done!'); });

// 或者你可以在流中使用 `.next()` 来手动地获取下一个文档
// `.next()` 返回一个 Promise,因此你可以使用 promises 或者 callbacks。
var cursor = Thing.find({ name: /^hello/ }).cursor();
cursor.next(function(error, doc) {
  console.log(doc);
});

// 因为 `.next()` 返回一个 promise,
// 因此你可以使用 co 来简化迭代所有文档
// 而不是将他们全部加载到内存中 you can use co
co(function*() {
  const cursor = Thing.find({ name: /^hello/ }).cursor();
  for (let doc = yield cursor.next(); doc != null; doc = yield cursor.next()) {
    console.log(doc);
  }
});
可用的选项:
  • transform: 一个可选的函数,接受一个 mongoose 文档作为参数。函数的返回值将在 data 上被发射,然后由 .next() 返回。
源码
Query.prototype.cursor = function cursor(opts) {
  this._applyPaths();
  this._fields = this._castFields(this._fields);
  this.setOptions({ fields: this._fieldsForExec() });
  if (opts) {
    this.setOptions(opts);
  }

  try {
    this.cast(this.model);
  } catch (err) {
    return (new QueryCursor(this, this.options))._markError(err);
  }

  return new QueryCursor(this, this.options);
};

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

17.15. Query#deleteMany([filter], [callback])

Declare and/or execute this query as a deleteMany() operation. Works like remove, except it deletes every document that matches criteria in the collection, regardless of the value of single.

参数:
  • [filter] <Object, Query> mongodb selector

  • [callback] <Function> optional params are (error, writeOpResult)

返回值:
参见:

This function does not trigger any middleware

示例:
Character.deleteMany({ name: /Stark/, age: { $gte: 18 } }, callback)
Character.deleteMany({ name: /Stark/, age: { $gte: 18 } }).then(next)
源码
Query.prototype.deleteMany = function(filter, callback) {
  if (typeof filter === 'function') {
    callback = filter;
    filter = null;
  }

  filter = utils.toObject(filter, { retainKeyOrder: true });

  try {
    this.cast(this.model, filter);
    this.merge(filter);
  } catch (err) {
    this.error(err);
  }

  prepareDiscriminatorCriteria(this);

  if (!callback) {
    return Query.base.deleteMany.call(this);
  }

  return this._deleteMany.call(this, callback);
};

17.16. Query#deleteOne([filter], [callback])

Declare and/or execute this query as a deleteOne() operation. Works like remove, except it deletes at most one document regardless of the single option.

参数:
  • [filter] <Object, Query> mongodb selector

  • [callback] <Function> optional params are (error, writeOpResult)

返回值:
参见:

This function does not trigger any middleware.

示例:
Character.deleteOne({ name: 'Eddard Stark' }, callback)
Character.deleteOne({ name: 'Eddard Stark' }).then(next)
源码
Query.prototype.deleteOne = function(filter, callback) {
  if (typeof filter === 'function') {
    callback = filter;
    filter = null;
  }

  filter = utils.toObject(filter, { retainKeyOrder: true });

  try {
    this.cast(this.model, filter);
    this.merge(filter);
  } catch (err) {
    this.error(err);
  }

  prepareDiscriminatorCriteria(this);

  if (!callback) {
    return Query.base.deleteOne.call(this);
  }

  return this._deleteOne.call(this, callback);
};

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

Declares or executes a distict() operation.

参数:
返回值:
参见:

Passing a callback executes the query.

This function does not trigger any middleware.

示例:
distinct(field, conditions, callback)
distinct(field, conditions)
distinct(field, callback)
distinct(field)
distinct(callback)
distinct()
源码
Query.prototype.distinct = function(field, conditions, callback) {
  if (!callback) {
    if (typeof conditions === 'function') {
      callback = conditions;
      conditions = undefined;
    } else if (typeof field === 'function') {
      callback = field;
      field = undefined;
      conditions = undefined;
    }
  }

  conditions = utils.toObject(conditions);

  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);
};

17.18. Query#elemMatch(path, criteria)

Specifies an $elemMatch condition

参数:
  • path

  • criteria

返回值:
参见:
示例:
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);
})

17.19. Query#equals(val)

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

参数:
返回值:
示例:
User.where('age').equals(49);


// is the same as

User.where('age', 49);

17.20. Query#error(err)

Gets/sets the error flag on this query. If this flag is not null or undefined, the exec() promise will reject without executing.

参数:
  • err if set, exec() will fail fast before sending the query to MongoDB
示例:
Query().error(); // Get current error value
Query().error(null); // Unset the current error
Query().error(new Error('test')); // `exec()` will resolve with test
Schema.pre('find', function() {
  if (!this.getQuery().userId) {
    this.error(new Error('Not allowed to query without setting userId'));
  }
});

Note that query casting runs after hooks, so cast errors will override custom errors.

示例:
var TestSchema = new Schema({ num: Number });
var TestModel = db.model('Test', TestSchema);
TestModel.find({ num: 'not a number' }).error(new Error('woops')).exec(function(error) {
  // `error` will be a cast error because `num` failed to cast
});
源码
Query.prototype.error = function error(err) {
  if (arguments.length === 0) {
    return this._error;
  }

  this._error = err;
  return this;
};

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

执行查询

参数:
  • [operation]

  • [callback] <Function> 可选, 参数依赖于被调用的函数

返回值:

<Promise>

示例:
var promise = query.exec();
var promise = query.exec('update');

query.exec(callback);
query.exec('find', callback);
源码
Query.prototype.exec = function exec(op, callback) {
  var Promise = PromiseProvider.get();
  var _this = this;

  if (typeof op === 'function') {
    callback = op;
    op = null;
  } else if (typeof op === 'string') {
    this.op = op;
  }

  var _results;
  var promise = new Promise.ES6(function(resolve, reject) {
    if (!_this.op) {
      resolve();
      return;
    }

    _this[_this.op].call(_this, function(error, res) {
      if (error) {
        reject(error);
        return;
      }
      _results = arguments;
      resolve(res);
    });
  });

  if (callback) {
    promise.then(
      function() {
        callback.apply(null, _results);
        return null;
      },
      function(error) {
        callback(error, null);
      }).
      catch(function(error) {
        // If we made it here, we must have an error in the callback re:
        // gh-4500, so we need to emit.
        setImmediate(function() {
          _this.model.emit('error', error);
        });
      });
  }

  return promise;
};

17.22. Query#exists([path], val)

Specifies an $exists condition

参数:
返回值:
参见:
示例:

// { 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);

17.23. Query#find([filter], [callback])

查找文档

参数:
返回值:

<Query> this

When no callback is passed, the query is not executed. When the query is executed, the result will be an array of documents.

示例:
query.find({ name: 'Los Pollos Hermanos' }).find(callback)
源码
Query.prototype.find = function(conditions, callback) {
  if (typeof conditions === 'function') {
    callback = conditions;
    conditions = {};
  }

  conditions = utils.toObject(conditions);

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

    prepareDiscriminatorCriteria(this);
  } else if (conditions != null) {
    this.error(new ObjectParameterError(conditions, 'filter', 'find'));
  }

  // if we don't have a callback, then just return the query object
  if (!callback) {
    return Query.base.find.call(this);
  }

  this._find(callback);

  return this;
};

17.24. Query#findOne([filter], [projection], [options], [callback])

将查询声明为一个 findOne 操作。执行时,第一个被找到的文档被传递给回调。

参数:
  • [filter] <Object> mongodb selector

  • [projection] <Object> optional fields to return

  • [options] <Object> see setOptions()

  • [callback] <Function> optional params are (error, document)

返回值:
参见:

Passing a callback executes the query. The result of the query is a single document.

注意:

conditions is optional, and if conditions is null or undefined, mongoose will send an empty findOne command to MongoDB, which will return an arbitrary document. If you're querying by _id, use Model.findById() instead.

该函数触发以下中间件

  • findOne()
示例:
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
  }
});
源码
Query.prototype.findOne = function(conditions, projection, options, callback) {
  if (typeof conditions === 'function') {
    callback = conditions;
    conditions = null;
    projection = null;
    options = null;
  } else if (typeof projection === 'function') {
    callback = projection;
    options = null;
    projection = null;
  } else if (typeof options === 'function') {
    callback = options;
    options = null;
  }

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

  this.op = 'findOne';

  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.error(null);
    } catch (err) {
      this.error(err);
    }
  } else if (conditions != null) {
    this.error(new ObjectParameterError(conditions, 'filter', 'findOne'));
  }

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

  this._findOne(callback);

  return this;
};

17.25. Query#findOneAndRemove([conditions], [options], [options.passRawResult], [options.strict], [callback])

Issues a mongodb findAndModify remove command.

参数:
  • [conditions] <Object>

  • [options] <Object>

  • [options.passRawResult] <Boolean> if true, passes the raw result from the MongoDB driver as the third callback parameter

  • [options.strict] overwrites the schema's strict mode option

  • [callback] <Function> optional params are (error, document)

返回值:
参见:

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

该函数触发以下中间件

  • findOneAndRemove()
可用选项
  • sort: if multiple docs are found by the conditions, sets the sort order to choose which doc to update
  • maxTimeMS: puts a time limit on the query - requires mongodb >= 2.6.0
  • passRawResult: if true, passes the raw result from the MongoDB driver as the third callback parameter
回调函数签名
function(error, doc, result) {
  // error: any errors that occurred
  // doc: the document before updates are applied if `new: false`, or after updates if `new = true`
  // result: [raw result from the MongoDB driver](http://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#findAndModify)
}
示例:
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

17.26. Query#findOneAndUpdate(query, [doc], [options], [options.passRawResult], [options.strict], [options.multipleCastError], [callback])

Issues a mongodb findAndModify update command.

参数:
返回值:
参见:

找到一个匹配的文档,根据 update 参数更新它,传递任何选项,并将找到的文档(如果有的话)返回给回调。如果传入了回调,查询将立即执行。

该函数触发以下中间件

  • findOneAndUpdate()
可用选项
  • new: bool - 如果为 true,返回修改后的文档,而不是原始文件。 默认为 false (changed in 4.0)
  • upsert: bool - 如果不存在,就创建对象。 默认为 false
  • fields: {Object|String} - 字段选择. 等价于 .select(fields).findOneAndUpdate()
  • sort: 如果在条件下找到了多个文档,设置排序顺序来选择要更新的文档
  • maxTimeMS: 对查询的时间限制 - 需要 mongodb >= 2.6.0
  • runValidators: 如果 true,在此命令上运行更新验证器。更新验证器根据模型的模式的定义验证更新操作。
  • setDefaultsOnInsert: 如果这个选项和 upsert 都为 true,那么如果一个新文档被创建,那么 mongoose 将应用模型模式中指定的默认值。这个选项只适用于 MongoDB >= 2.4,因为它依赖于 MongoDB 的 $setOnInsert 操作符
  • passRawResult: 如果为 true,将 MongoDB 驱动器的原始结果作为第三个回调参数传入
  • context (string) 如果设置为 “query” 并且 runValidators 打开,这将在自定义的验证器函数引用这个 “query”,更新验证运行。如果 runValidatorsfalse,则什么都不做。
  • runSettersOnQuery: bool - 如果为 true,为所有在查询和更新中定义的字段运行「所有在相关模型的模式中定义的 setter」
回调函数签名
function(error, doc) {
  // error: any errors that occurred
  // doc: the document before updates are applied if `new: false`, or after updates if `new = true`
}
示例:
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

17.27. Query#geometry(object)

Specifies a $geometry condition

参数:
  • object <Object> Must contain a type property which is a String and a coordinates property which is an Array. See the examples.
返回值:
参见:
示例:

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().

注意:

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

The object argument must contain type and coordinates properties.

  • type {String}
  • coordinates {Array}

17.28. Query#getQuery()

Returns the current query conditions as a JSON object.

返回值:
  • <Object> current query conditions
示例:
var query = new Query();
query.find({ a: 1 }).where('b').gt(2);
query.getQuery(); // { a: 1, b: { $gt: 2 } }
源码
Query.prototype.getQuery = function() {
  return this._conditions;
};

17.29. Query#getUpdate()

Returns the current update operations as a JSON object.

返回值:
  • <Object> current update operations
示例:
var query = new Query();
query.update({}, { $set: { a: 5 } });
query.getUpdate(); // { $set: { a: 5 } }
源码
Query.prototype.getUpdate = function() {
  return this._update;
};

17.30. Query#gt([path], val)

Specifies a $gt query condition.

参数:
参见:

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

示例:
Thing.find().where('age').gt(21)

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

17.31. Query#gte([path], val)

Specifies a $gte query condition.

参数:
参见:

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

17.32. Query#hint(val)

Sets query hints.

参数:
返回值:
参见:
示例:
query.hint({ indexA: 1, indexB: -1})
注意:

Cannot be used with distinct()

17.33. Query#in([path], val)

Specifies an $in query condition.

参数:
参见:

$in

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

17.34. Query#intersects([arg])

Declares an intersects query for geometry().

参数:
返回值:
参见:
示例:
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]]
})
注意:

MUST be used after where().

注意:

In Mongoose 3.7, intersects changed from a getter to a function. If you need the old syntax, use this.

17.35. Query#lean(bool)

设置 lean 选项。

参数:
返回值:

使用 lean 选项的查询返回的文档是普通的 javascript 对象,而不是 Mongoose 文档。 它们没有 save 方法、getter/setter 或其他 Mongoose 的神奇应用。

示例:
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
});

在高性能只读场景中,这是一个很好的选择,特别是在与流结合的情况下。

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

17.36. Query#limit(val)

Specifies the maximum number of documents the query will return.

参数:
示例:
query.limit(20)
注意:

Cannot be used with distinct()

17.37. Query#lt([path], val)

Specifies a $lt query condition.

参数:
参见:

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

17.38. Query#lte([path], val)

Specifies a $lte query condition.

参数:
参见:

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

17.39. Query#maxDistance([path], val)

Specifies a $maxDistance query condition.

参数:
参见:

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

17.40. Query#maxscan()

DEPRECATED Alias of maxScan

参见:

17.41. Query#maxScan(val)]()

Specifies the maxScan option.

参数:
参见:
示例:
query.maxScan(100)
注意:

Cannot be used with distinct()

17.42. Query#merge(source)

Merges another Query or conditions object into this one.

参数:
  • source
返回值:

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

源码
Query.prototype.merge = function(source) {
  if (!source) {
    return this;
  }

  var opts = { retainKeyOrder: this.options.retainKeyOrder, overwrite: true };

  if (source instanceof Query) {
    // if source has a feature, apply it to ourselves

    if (source._conditions) {
      utils.merge(this._conditions, source._conditions, opts);
    }

    if (source._fields) {
      this._fields || (this._fields = {});
      utils.merge(this._fields, source._fields, opts);
    }

    if (source.options) {
      this.options || (this.options = {});
      utils.merge(this.options, source.options, opts);
    }

    if (source._update) {
      this._update || (this._update = {});
      utils.mergeClone(this._update, source._update);
    }

    if (source._distinct) {
      this._distinct = source._distinct;
    }

    return this;
  }

  // plain object
  utils.merge(this._conditions, source, opts);

  return this;
};

17.43. Query#merge(source)

Merges another Query or conditions object into this one.

参数:
  • source
返回值:

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

New in 3.7.0

17.44. Query#mod([path], val)

Specifies a $mod condition, filters documents for documents whose path property is a number that is equal to remainder modulo divisor.

参数:
  • [path] <String>

  • val <Array> must be of length 2, first element is divisor, 2nd element is remainder.

返回值:
参见:
示例:
// All find products whose inventory is odd
Product.find().mod('inventory', [2, 1]);
Product.find().where('inventory').mod([2, 1]);
// This syntax is a little strange, but supported.
Product.find().where('inventory').mod(2, 1);

17.45. Query#mongooseOptions(options)

Getter/setter around the current mongoose-specific options for this query (populate, lean, etc.)

参数:
  • options <Object> if specified, overwrites the current options
    源码
    Query.prototype.mongooseOptions = function(v) {
    if (arguments.length > 0) {
    this._mongooseOptions = v;
    }
    return this._mongooseOptions;
    };
    

17.46. Query#ne([path], val)

Specifies a $ne query condition.

参数:
参见:

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

17.47. Query#near([path], val)

Specifies a $near or $nearSphere condition

参数:
返回值:
参见:

These operators return documents sorted by distance.

示例:
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 });

17.48. Query#nearSphere()

DEPRECATED Specifies a $nearSphere condition

参见:
示例:
query.where('loc').nearSphere({ center: [10, 10], maxDistance: 5 });

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

示例:
query.where('loc').near({ center: [10, 10], spherical: true });
源码
Query.prototype.nearSphere = function() {
  this._mongooseOptions.nearSphere = true;
  this.near.apply(this, arguments);
  return this;
};

17.49. Query#nin([path], val)

Specifies an $nin query condition.

参数:
参见:

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

17.50. Query#nor(array)

Specifies arguments for a $nor condition.

参数:
  • array <Array> array of conditions
返回值:
参见:
示例:
query.nor([{ color: 'green' }, { status: 'ok' }])

17.51. Query#or(array)

Specifies arguments for an $or condition.

参数:
  • array <Array> array of conditions
返回值:
参见:
示例:
query.or([{ color: 'red' }, { status: 'emergency' }])

17.52. Query#polygon([path], [coordinatePairs...])

Specifies a $polygon condition

参数:
  • [path]

  • [coordinatePairs...]

返回值:
参见:
示例:
query.where('loc').within().polygon([10,20], [13, 25], [7,15])
query.polygon('loc', [10,20], [13, 25], [7,15])

17.53. Query#populate(path, [select], [model], [match], [options])

Specifies paths which should be populated with other documents.

参数:
  • path either the path to populate or an object specifying all parameters

  • [select] Field selection for the population query

  • [model] The model you wish to use for population. If not specified, populate will look up the model by the name in the Schema's ref field.

  • [match] <Object> Conditions for the population query

  • [options] <Object> Options for the population query (sort, etc)

返回值:
参见:
示例:
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.

源码
Query.prototype.populate = function() {
  if (arguments.length === 0) {
    return this;
  }

  var i;

  var res = utils.populate.apply(null, arguments);

  // Propagate readPreference from parent query, unless one already specified
  if (this.options && this.options.readPreference != null) {
    for (i = 0; i < res.length; ++i) {
      if (!res[i].options || res[i].options.readPreference == null) {
        res[i].options = res[i].options || {};
        res[i].options.readPreference = this.options.readPreference;
      }
    }
  }

  var opts = this._mongooseOptions;

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

  var pop = opts.populate;

  for (i = 0; i < res.length; ++i) {
    var path = res[i].path;
    if (pop[path] && pop[path].populate && res[i].populate) {
      res[i].populate = pop[path].populate.concat(res[i].populate);
    }
    pop[res[i].path] = res[i];
  }

  return this;
};

17.54. Query#read(pref, [tags])

Determines the MongoDB nodes from which to read.

参数:
  • pref <String> one of the listed preference options or aliases

  • [tags] <Array> optional tags for this query

返回值:
参见:
引用:
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.

别名:

p   primary
pp  primaryPreferred
s   secondary
sp  secondaryPreferred
n   nearest
示例:
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 and here.

17.55. Query#regex([path], val)

Specifies a $regex query condition.

参数:
参见:

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

17.56. Query#remove([filter], [callback])

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

参数:
  • [filter] <Object, Query> mongodb selector

  • [callback] <Function> optional params are (error, writeOpResult)

返回值:
参见:

This function does not trigger any middleware

示例:
Model.remove({ artist: 'Anne Murray' }, callback)
注意:

The operation is only executed when a callback is passed. To force execution without a callback, you 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
query.exec()

// summary
query.remove(conds, fn); // executes
query.remove(conds)
query.remove(fn) // executes
query.remove()
源码
Query.prototype.remove = function(filter, callback) {
  if (typeof filter === 'function') {
    callback = filter;
    filter = null;
  }

  filter = utils.toObject(filter, { retainKeyOrder: true });

  try {
    this.cast(this.model, filter);
    this.merge(filter);
  } catch (err) {
    this.error(err);
  }

  prepareDiscriminatorCriteria(this);

  if (!callback) {
    return Query.base.remove.call(this);
  }

  return this._remove(callback);
};

17.57. Query#replaceOne([criteria], [doc], [options], [callback])

Declare and/or execute this query as a replaceOne() operation. Same as update(), except MongoDB will replace the existing document and will not accept any atomic operators ($set, etc.)

参数:
  • [criteria] <Object>

  • [doc] <Object> the update command

  • [options] <Object>

  • [callback] <Function> optional params are (error, writeOpResult)

返回值:
参见:
注意:

replaceOne will not fire update middleware. Use pre('replaceOne') and post('replaceOne') instead.

该函数触发以下中间件

  • replaceOne()
源码
Query.prototype.replaceOne = function(conditions, doc, options, callback) {
  if (typeof options === 'function') {
    // .update(conditions, doc, callback)
    callback = options;
    options = null;
  } else if (typeof doc === 'function') {
    // .update(doc, callback);
    callback = doc;
    doc = conditions;
    conditions = {};
    options = null;
  } else if (typeof conditions === 'function') {
    // .update(callback)
    callback = conditions;
    conditions = undefined;
    doc = undefined;
    options = undefined;
  } else if (typeof conditions === 'object' && !doc && !options && !callback) {
    // .update(doc)
    doc = conditions;
    conditions = undefined;
    options = undefined;
    callback = undefined;
  }

  this.setOptions({ overwrite: true });
  return _update(this, 'replaceOne', conditions, doc, options, callback);
};

17.58. Query#select(arg)

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

参数:
  • arg
返回值:
参见:

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.

A projection must be either inclusive or exclusive. In other words, you must either list the fields to include (which excludes all others), or list the fields to exclude (which implies all other fields are included). The _id field is the only exception because MongoDB includes it by default.

示例:
// 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')

17.59. Query#selected()

Determines if field selection has been made.

返回值:

17.60. Query#selectedExclusively()

Determines if exclusive field selection has been made.

返回值:
query.selectedExclusively() // false
query.select('-name')
query.selectedExclusively() // true
query.selectedInclusively() // false

17.61. Query#selectedInclusively()

Determines if inclusive field selection has been made.

返回值:
query.selectedInclusively() // false
query.select('name')
query.selectedInclusively() // true

17.62. Query#setOptions(options)

设置查询选项。有些选项只对某些操作是有意义的。

参数:
选项:

以下选项仅用于 find():

以下选项仅适用于 update(), updateOne(), updateMany(), replaceOne(), 和 findOneAndUpdate():

以下选项仅适用于 find(), findOne(), findById(), 和 findOneAndUpdate():

以下选项适用于所有操作

源码
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 == null) {
    return this;
  }

  if (Array.isArray(options.populate)) {
    var populate = options.populate;
    delete options.populate;
    var _numPopulate = populate.length;
    for (var i = 0; i < _numPopulate; ++i) {
      this.populate(populate[i]);
    }
  }

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

17.63. Query#size([path], val)

Specifies a $size query condition.

参数:
参见:

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

示例:
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);
})

17.64. Query#skip(val)

指定要跳过的文档的数量。

参数:
参见:
示例:
query.skip(100).limit(20)
注意:

Cannot be used with distinct()

17.65. Query#slaveOk(v)

DEPRECATED Sets the slaveOk option.

参数:
返回值:
参见:

Deprecated in MongoDB 2.2 in favor of read preferences.

示例:
query.slaveOk() // true
query.slaveOk(true)
query.slaveOk(false)

17.66. Query#slice([path], val)

Specifies a $slice projection for an array.

参数:
  • [path] <String>

  • val <Number> number/range of elements to slice

返回值:
参见:
示例:
query.slice('comments', 5)
query.slice('comments', -5)
query.slice('comments', [10, 5])
query.where('comments').slice(5)
query.where('comments').slice([-10, 5])

17.67. Query#slice([path], [val])

Specifies a path for use with chaining.

参数:
  • [path]

  • [val]

返回值:
示例:
// 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)

17.68. Query#snapshot()

Specifies this query as a snapshot query.

返回值:
参见:
示例:
query.snapshot() // true
query.snapshot(true)
query.snapshot(false)
注意:

Cannot be used with distinct()

17.69. Query#sort(arg)

设置排序顺序

参数:
  • arg
返回值:
参见:

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.

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

// equivalent
query.sort('field -test');
注意:

Cannot be used with distinct()

源码
Query.prototype.sort = function(arg) {
  if (arguments.length > 1) {
    throw new Error('sort() only takes 1 Argument');
  }

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

17.70. Query#stream([options])

Returns a Node.js 0.8 style read stream interface.

参数:
返回值:
参见:
示例:
// 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
});
可用选项
  • transform: optional function which accepts a mongoose document. The return value of the function will be emitted on data.
示例:
// JSON.stringify all documents before emitting
var stream = Thing.find().stream({ transform: JSON.stringify });
stream.pipe(writeStream);
源码
Query.prototype.stream = function stream(opts) {
  this._applyPaths();
  this._fields = this._castFields(this._fields);
  this._castConditions();
  return new QueryStream(this, opts);
};
Query.prototype.stream = util.deprecate(Query.prototype.stream, 'Mongoose: ' +
  'Query.prototype.stream() is deprecated in mongoose >= 4.5.0, ' +
  'use Query.prototype.cursor() instead');

17.71. Query#tailable(bool, [opts], [opts.numberOfRetries], [opts.tailableRetryInterval])

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

参数:
  • bool <Boolean> defaults to true

  • [opts] <Object> options to set

  • [opts.numberOfRetries] <Number> if cursor is exhausted, retry this many times before giving up

  • [opts.tailableRetryInterval] <Number> if cursor is exhausted, wait this many milliseconds before retrying

参见:
示例:
query.tailable() // true
query.tailable(true)
query.tailable(false)
注意:

Cannot be used with distinct()

源码
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);
};

17.72. Query#then([resolve], [reject])

Executes the query returning a Promise which will be resolved with either the doc(s) or rejected with the error.

参数:
返回值:
源码
Query.prototype.then = function(resolve, reject) {
  return this.exec().then(resolve, reject);
};

17.73. Query#toConstructor()

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

返回值:
  • <Query> subclass-of-Query
示例:
// 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

源码
Query.prototype.toConstructor = function toConstructor() {
  var model = this.model;
  var coll = this.mongooseCollection;

  var CustomQuery = function(criteria, options) {
    if (!(this instanceof CustomQuery)) {
      return new CustomQuery(criteria, options);
    }
    this._mongooseOptions = utils.clone(p._mongooseOptions);
    Query.call(this, criteria, options || null, model, coll);
  };

  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, { retainKeyOrder: true });
  p._fields = utils.clone(this._fields);
  p._update = utils.clone(this._update, {
    flattenDecimals: false,
    retainKeyOrder: true
  });
  p._path = this._path;
  p._distinct = this._distinct;
  p._collection = this._collection;
  p._mongooseOptions = this._mongooseOptions;

  return CustomQuery;
};

17.74. Query#update([criteria], [doc], [options], [options.multipleCastError], [callback])

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

参数:
  • [criteria] <Object>

  • [doc] <Object> the update command

  • [options] <Object>

  • [options.multipleCastError] <Boolean> by default, mongoose only returns the first error that occurred in casting the query. Turn on this option to aggregate all the cast errors.

  • [callback] <Function> optional, params are (error, writeOpResult)

返回值:
参见:

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

该函数触发以下中间件

  • update()
示例:
Model.where({ _id: id }).update({ title: 'words' })

// becomes

Model.where({ _id: id }).update({ $set: { title: 'words' }})
可用选项:
  • 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)
  • runValidators: 如果 true,在此命令上运行更新验证器。更新验证器根据模型的模式的定义验证更新操作。
  • setDefaultsOnInsert: if this and upsert are true, mongoose will apply the defaults specified in the model's schema if a new document is created. This option only works on MongoDB >= 2.4 because it relies on MongoDB 的 $setOnInsert 操作符
  • strict (boolean) overrides the strict option for this update
  • overwrite (boolean) disables update-only mode, allowing you to overwrite the doc (false)
  • context (string) if set to 'query' and runValidators is on, this will refer to the query in custom validator functions that update validation runs. Does nothing if runValidators is false.
注意:

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.

注意:

The operation is only executed when a callback is passed. To force execution without a callback, 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

// 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 总结

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
update()
源码
Query.prototype.update = function(conditions, doc, options, callback) {
  if (typeof options === 'function') {
    // .update(conditions, doc, callback)
    callback = options;
    options = null;
  } else if (typeof doc === 'function') {
    // .update(doc, callback);
    callback = doc;
    doc = conditions;
    conditions = {};
    options = null;
  } else if (typeof conditions === 'function') {
    // .update(callback)
    callback = conditions;
    conditions = undefined;
    doc = undefined;
    options = undefined;
  } else if (typeof conditions === 'object' && !doc && !options && !callback) {
    // .update(doc)
    doc = conditions;
    conditions = undefined;
    options = undefined;
    callback = undefined;
  }

  return _update(this, 'update', conditions, doc, options, callback);
};

17.75. Query#updateMany([criteria], [doc], [options], [callback])

Declare and/or execute this query as an updateMany() operation. Same as update(), except MongoDB will update all documents that match criteria (as opposed to just the first one) regardless of the value of the multi option.

参数:
  • [criteria] <Object>

  • [doc] <Object> the update command

  • [options] <Object>

  • [callback] <Function> optional params are (error, writeOpResult)

返回值:
参见:
注意:

updateMany will not fire update middleware. Use pre('updateMany') and post('updateMany') instead.

该函数触发以下中间件

  • updateMany()

    源码
    Query.prototype.updateMany = function(conditions, doc, options, callback) {
    if (typeof options === 'function') {
    // .update(conditions, doc, callback)
    callback = options;
    options = null;
    } else if (typeof doc === 'function') {
    // .update(doc, callback);
    callback = doc;
    doc = conditions;
    conditions = {};
    options = null;
    } else if (typeof conditions === 'function') {
    // .update(callback)
    callback = conditions;
    conditions = undefined;
    doc = undefined;
    options = undefined;
    } else if (typeof conditions === 'object' && !doc && !options && !callback) {
    // .update(doc)
    doc = conditions;
    conditions = undefined;
    options = undefined;
    callback = undefined;
    }
    
    return _update(this, 'updateMany', conditions, doc, options, callback);
    };
    

17.76. Query#updateOne([criteria], [doc], [options], [callback])

Declare and/or execute this query as an updateOne() operation. Same as update(), except MongoDB will update only the first document that matches criteria regardless of the value of the multi option.

参数:
  • [criteria] <Object>

  • [doc] <Object> the update command

  • [options] <Object>

  • [callback] <Function> params are (error, writeOpResult)

返回值:
参见:
注意:

updateOne will not fire update middleware. Use pre('updateOne') and post('updateOne') instead.

该函数触发以下中间件

  • updateOne()

    源码
    Query.prototype.updateOne = function(conditions, doc, options, callback) {
    if (typeof options === 'function') {
    // .update(conditions, doc, callback)
    callback = options;
    options = null;
    } else if (typeof doc === 'function') {
    // .update(doc, callback);
    callback = doc;
    doc = conditions;
    conditions = {};
    options = null;
    } else if (typeof conditions === 'function') {
    // .update(callback)
    callback = conditions;
    conditions = undefined;
    doc = undefined;
    options = undefined;
    } else if (typeof conditions === 'object' && !doc && !options && !callback) {
    // .update(doc)
    doc = conditions;
    conditions = undefined;
    options = undefined;
    callback = undefined;
    }
    
    return _update(this, 'updateOne', conditions, doc, options, callback);
    };
    

17.77. Query#within()

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

返回值:
参见:
示例:
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().

注意:

As of Mongoose 3.7, $geoWithin is always used for queries. To change this behavior, see Query.use$geoWithin.

注意:

In Mongoose 3.7, within changed from a getter to a function. If you need the old syntax, use this.

17.78. Query#use$geoWithin

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.

源码
Query.use$geoWithin = mquery.use$geoWithin;
参见:

http://docs.mongodb.org/manual/reference/operator/geoWithin/


18. aggregate.js

源码:aggregate.js

18.1. Aggregate#addCursorFlag(flag, value)

Adds a cursor flag

参数:
参见:
示例:
Model.aggregate(..).addCursorFlag('noCursorTimeout', true).exec();
源码
Aggregate.prototype.addCursorFlag = function(flag, value) {
  if (!this.options) {
    this.options = {};
  }
  this.options[flag] = value;
  return this;
};

18.2. Aggregate#addFields(arg)

Appends a new $addFields operator to this aggregate pipeline. Requires MongoDB v3.4+ to work

参数:
  • arg <Object> field specification
返回值:
参见:
示例:
// adding new fields based on existing fields
aggregate.addFields({
    newField: '$b.nested'
  , plusTen: { $add: ['$val', 10]}
  , sub: {
       name: '$a'
    }
})

// etc
aggregate.addFields({ salary_k: { $divide: [ "$salary", 1000 ] } });
源码
Aggregate.prototype.addFields = function(arg) {
  var fields = {};
  if (typeof arg === 'object' && !util.isArray(arg)) {
    Object.keys(arg).forEach(function(field) {
      fields[field] = arg[field];
    });
  } else {
    throw new Error('Invalid addFields() argument. Must be an object');
  }
  return this.append({$addFields: fields});
};

18.3. Aggregate([ops])

Aggregate constructor used for building aggregation pipelines.

参数:
  • [ops] aggregation operator(s) or operator array
参见:
示例:
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().

示例:
Model
.aggregate({ $match: { age: { $gte: 21 }}})
.unwind('tags')
.exec(callback)
注意:
  • The documents returned are plain javascript objects, not mongoose documents (since any shape of document can be returned).
  • Requires MongoDB >= 2.1
  • Mongoose does not cast pipeline stages. new Aggregate({ $match: { _id: '00000000000000000000000a' } }); will not work unless _id is a string in the database. Use new Aggregate({ $match: { _id: mongoose.Types.ObjectId('00000000000000000000000a') } }); instead.
源码
function Aggregate() {
  this._pipeline = [];
  this._model = undefined;
  this.options = {};

  if (arguments.length === 1 && util.isArray(arguments[0])) {
    this.append.apply(this, arguments[0]);
  } else {
    this.append.apply(this, arguments);
  }
}

18.4. Aggregate#allowDiskUse(value, [tags])

Sets the allowDiskUse option for the aggregation query (ignored for < 2.6.0)

参数:
  • value <Boolean> Should tell server it can use hard drive to store data during aggregation.

  • [tags] <Array> optional tags for this query

参见:
示例:
Model.aggregate(..).allowDiskUse(true).exec(callback)
源码
Aggregate.prototype.allowDiskUse = function(value) {
  this.options.allowDiskUse = value;
  return this;
};

18.5. Aggregate#append(ops)

Appends new operators to this aggregate pipeline

参数:
  • ops <Object> operator(s) to append
返回值:
示例:
aggregate.append({ $project: { field: 1 }}, { $limit: 2 });

// or pass an array
var pipeline = [{ $match: { daw: 'Logic Audio X' }} ];
aggregate.append(pipeline);
源码
Aggregate.prototype.append = function() {
  var args = (arguments.length === 1 && 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;
};

18.6. Aggregate#collation(collation, value)

Adds a collation

参数:
参见:
示例:

Model.aggregate(..).collation({ locale: 'en_US', strength: 1 }).exec();

源码

Aggregate.prototype.collation = function(collation) {
  if (!this.options) {
    this.options = {};
  }
  this.options.collation = collation;
  return this;
};

18.7. Aggregate#cursor(options, options.batchSize, [options.useMongooseAggCursor])

Sets the cursor option option for the aggregation query (ignored for < 2.6.0). Note the different syntax below: .exec() returns a cursor object, and no callback is necessary.

参数:
  • options <Object>

  • options.batchSize <Number> set the cursor batch size

  • [options.useMongooseAggCursor] <Boolean> use experimental mongoose-specific aggregation cursor (for eachAsync() and other query cursor semantics)

参见:
示例:
var cursor = Model.aggregate(..).cursor({ batchSize: 1000 }).exec();
cursor.each(function(error, doc) {
  // use doc
});
源码
Aggregate.prototype.cursor = function(options) {
  if (!this.options) {
    this.options = {};
  }
  this.options.cursor = options || {};
  return this;
};

18.8. Aggregate#exec([callback])

Executes the aggregate pipeline on the currently bound Model.

参数:
返回值:
参见:
示例:
aggregate.exec(callback);

// Because a promise is returned, the `callback` is optional.
var promise = aggregate.exec();
promise.then(..);
源码
Aggregate.prototype.exec = function(callback) {
  if (!this._model) {
    throw new Error('Aggregate not bound to any Model');
  }
  var _this = this;
  var model = this._model;
  var Promise = PromiseProvider.get();
  var options = utils.clone(this.options || {});
  var pipeline = this._pipeline;
  var collection = this._model.collection;

  if (options && options.cursor) {
    if (options.cursor.async) {
      delete options.cursor.async;
      return new Promise.ES6(function(resolve) {
        if (!collection.buffer) {
          process.nextTick(function() {
            var cursor = collection.aggregate(pipeline, options);
            decorateCursor(cursor);
            resolve(cursor);
            callback && callback(null, cursor);
          });
          return;
        }
        collection.emitter.once('queue', function() {
          var cursor = collection.aggregate(pipeline, options);
          decorateCursor(cursor);
          resolve(cursor);
          callback && callback(null, cursor);
        });
      });
    } else if (options.cursor.useMongooseAggCursor) {
      delete options.cursor.useMongooseAggCursor;
      return new AggregationCursor(this);
    }
    var cursor = collection.aggregate(pipeline, options);
    decorateCursor(cursor);
    return cursor;
  }

  return new Promise.ES6(function(resolve, reject) {
    if (!pipeline.length) {
      var err = new Error('Aggregate has empty pipeline');
      if (callback) {
        callback(err);
      }
      reject(err);
      return;
    }

    prepareDiscriminatorPipeline(_this);

    model.hooks.execPre('aggregate', _this, function(error) {
      if (error) {
        var _opts = { error: error };
        return model.hooks.execPost('aggregate', _this, [null], _opts, function(error) {
          if (callback) {
            callback(error);
          }
          reject(error);
        });
      }

      collection.aggregate(pipeline, options, function(error, result) {
        var _opts = { error: error };
        model.hooks.execPost('aggregate', _this, [result], _opts, function(error, result) {
          if (error) {
            if (callback) {
              callback(error);
            }
            reject(error);
            return;
          }

          if (callback) {
            callback(null, result);
          }
          resolve(result);
        });
      });
    });
  });
};

18.9. Aggregate#explain(callback)

Execute the aggregation with explain

参数:
返回值:
示例:
Model.aggregate(..).explain(callback)
源码
Aggregate.prototype.explain = function(callback) {
  var _this = this;
  var Promise = PromiseProvider.get();
  return new Promise.ES6(function(resolve, reject) {
    if (!_this._pipeline.length) {
      var err = new Error('Aggregate has empty pipeline');
      if (callback) {
        callback(err);
      }
      reject(err);
      return;
    }

    prepareDiscriminatorPipeline(_this);

    _this._model
        .collection
        .aggregate(_this._pipeline, _this.options || {})
        .explain(function(error, result) {
          if (error) {
            if (callback) {
              callback(error);
            }
            reject(error);
            return;
          }

          if (callback) {
            callback(null, result);
          }
          resolve(result);
        });
  });
};

18.10. Aggregate#facet(facet)

Combines multiple aggregation pipelines.

参数:
返回值:
  • this
参见:
示例:
Model.aggregate(...)
 .facet({
   books: [{ groupBy: '$author' }],
   price: [{ $bucketAuto: { groupBy: '$price', buckets: 2 } }]
 })
 .exec();

// Output: { books: [...], price: [{...}, {...}] }

源码

Aggregate.prototype.facet = function(options) {
  return this.append({$facet: options});
};

18.11. Aggregate#graphLookup(options)

Appends new custom $graphLookup operator(s) to this aggregate pipeline, performing a recursive search on a collection.

参数:
  • options <Object> to $graphLookup as described in the above link
返回值:
参见:
注意:

that graphLookup can only consume at most 100MB of memory, and does not allow disk use even if { allowDiskUse: true } is specified.

示例:
// Suppose we have a collection of courses, where a document might look like `{ _id: 0, name: 'Calculus', prerequisite: 'Trigonometry'}` and `{ _id: 0, name: 'Trigonometry', prerequisite: 'Algebra' }`
 aggregate.graphLookup({ from: 'courses', startWith: '$prerequisite', connectFromField: 'prerequisite', connectToField: 'name', as: 'prerequisites', maxDepth: 3 }) // this will recursively search the 'courses' collection up to 3 prerequisites
源码
Aggregate.prototype.graphLookup = function(options) {
  var cloneOptions = {};
  if (options) {
    if (!utils.isObject(options)) {
      throw new TypeError('Invalid graphLookup() argument. Must be an object.');
    }

    utils.mergeClone(cloneOptions, options);
    var startWith = cloneOptions.startWith;

    if (startWith && typeof startWith === 'string') {
      cloneOptions.startWith = cloneOptions.startWith.charAt(0) === '$' ?
        cloneOptions.startWith :
        '$' + cloneOptions.startWith;
    }

  }
  return this.append({ $graphLookup: cloneOptions });
};

18.12. Aggregate#group(arg)

Appends a new custom $group operator to this aggregate pipeline.

参数:
  • arg <Object> $group operator contents
返回值:
参见:
示例:
aggregate.group({ _id: "$department" });

18.13. Aggregate#limit(num)

Appends a new $limit operator to this aggregate pipeline.

参数:
  • num <Number> maximum number of records to pass to the next stage
返回值:
参见:
示例:
aggregate.limit(10);

18.14. Aggregate#lookup(options)

Appends new custom $lookup operator(s) to this aggregate pipeline.

参数:
  • options <Object> to $lookup as described in the above link
返回值:
参见:
示例:
aggregate.lookup({ from: 'users', localField: 'userId', foreignField: '_id', as: 'users' });
源码
Aggregate.prototype.lookup = function(options) {
  return this.append({$lookup: options});
};

18.15. Aggregate#match(arg)

Appends a new custom $match operator to this aggregate pipeline.

参数:
  • arg <Object> $match operator contents
返回值:
参见:
示例:
aggregate.match({ department: { $in: [ "sales", "engineering" ] } });

18.16. Aggregate#model(model)

Binds this aggregate to a model.

参数:
  • model the model to which the aggregate is to be bound
返回值:
源码
Aggregate.prototype.model = function(model) {
  this._model = model;
  if (model.schema != null) {
    if (this.options.readPreference == null &&
        model.schema.options.read != null) {
      this.options.readPreference = model.schema.options.read;
    }
    if (this.options.collation == null &&
        model.schema.options.collation != null) {
      this.options.collation = model.schema.options.collation;
    }
  }
  return this;
};

18.17. Aggregate#near(parameters)

Appends a new $geoNear operator to this aggregate pipeline.

参数:
返回值:
参见:
注意:

MUST be used as the first operator in the pipeline.

示例:
aggregate.near({
  near: [40.724, -73.997],
  distanceField: "dist.calculated", // required
  maxDistance: 0.008,
  query: { type: "public" },
  includeLocs: "dist.location",
  uniqueDocs: true,
  num: 5
});

18.18. Aggregate#option(value)

Lets you set arbitrary options, for middleware or plugins.

参数:
  • value <Object> keys to merge into current options
返回值:
  • this
参见:
示例:
var agg = Model.aggregate(..).option({ allowDiskUse: true }); // Set the `allowDiskUse` option
agg.options; // `{ allowDiskUse: true }`
源码
Aggregate.prototype.option = function(value) {
  for (var key in Object.keys(value)) {
    this.options[key] = value[key];
  }
  return this;
};

18.19. Aggregate#pipeline()

Returns the current pipeline

返回值:
示例:
MyModel.aggregate().match({ test: 1 }).pipeline(); // [{ $match: { test: 1 } }]
源码
Aggregate.prototype.pipeline = function() {
  return this._pipeline;
};

18.20. Aggregate#project(arg)

Appends a new $project operator to this aggregate pipeline.

参数:
  • arg field specification
返回值:
参见:

Mongoose query selection syntax is also supported.

示例:
// 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 ] } });
源码
Aggregate.prototype.project = function(arg) {
  var fields = {};

  if (typeof arg === 'object' && !util.isArray(arg)) {
    Object.keys(arg).forEach(function(field) {
      fields[field] = arg[field];
    });
  } else if (arguments.length === 1 && typeof arg === 'string') {
    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});
};

18.21. Aggregate#read(pref, [tags])

Sets the readPreference option for the aggregation query.

参数:
  • pref <String> one of the listed preference options or their aliases

  • [tags] <Array> optional tags for this query

参见:
示例:
Model.aggregate(..).read('primaryPreferred').exec(callback)
源码
Aggregate.prototype.read = function(pref, tags) {
  if (!this.options) {
    this.options = {};
  }
  read.call(this, pref, tags);
  return this;
};

18.22. Aggregate#sample(size)

Appepnds new custom $sample operator(s) to this aggregate pipeline.

参数:
  • size <Number> number of random documents to pick
返回值:
参见:
示例:
aggregate.sample(3); // Add a pipeline that picks 3 random documents
源码
Aggregate.prototype.sample = function(size) {
  return this.append({$sample: {size: size}});
};

18.23. Aggregate#skip(num)

Appends a new $skip operator to this aggregate pipeline.

参数:
  • num <Number> number of records to skip before next stage
返回值:
参见:
示例:
aggregate.skip(10);

18.24. Aggregate#sort(arg)

Appends a new $sort operator to this aggregate pipeline.

参数:
  • arg
返回值:
  • this
参见:

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.

示例:
// these are equivalent
aggregate.sort({ field: 'asc', test: -1 });
aggregate.sort('field -test');
源码
Aggregate.prototype.sort = function(arg) {
  // TODO refactor to reuse the query builder logic

  var sort = {};

  if (arg.constructor.name === 'Object') {
    var desc = ['desc', 'descending', -1];
    Object.keys(arg).forEach(function(field) {
      // If sorting by text score, skip coercing into 1/-1
      if (arg[field] instanceof Object && arg[field].$meta) {
        sort[field] = arg[field];
        return;
      }
      sort[field] = desc.indexOf(arg[field]) === -1 ? 1 : -1;
    });
  } else if (arguments.length === 1 && typeof arg === 'string') {
    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});
};

18.25. Aggregate#then([resolve], [reject])

Provides promise for aggregate.

参数:
返回值:
参见:
示例:
Model.aggregate(..).then(successCallback, errorCallback);
源码
Aggregate.prototype.then = function(resolve, reject) {
  return this.exec().then(resolve, reject);
};

18.26. Aggregate#unwind(fields)

Appends new custom $unwind operator(s) to this aggregate pipeline.

参数:
  • fields <String> the field(s) to unwind
返回值:
参见:
注意:

that the $unwind operator requires the path name to start with '$'. Mongoose will prepend '$' if the specified field doesn't start '$'.

示例:
aggregate.unwind("tags");
aggregate.unwind("a", "b", "c");
源码
Aggregate.prototype.unwind = function() {
  var args = utils.args(arguments);

  var res = [];
  for (var i = 0; i < args.length; ++i) {
    var arg = args[i];
    if (arg && typeof arg === 'object') {
      res.push({ $unwind: arg });
    } else if (typeof arg === 'string') {
      res.push({
        $unwind: (arg && arg.charAt(0) === '$') ? arg : '$' + arg
      });
    } else {
      throw new Error('Invalid arg "' + arg + '" to unwind(), ' +
        'must be string or object');
    }
  }

  return this.append.apply(this, res);
};

19. querystream.js

源码:querystream.js

19.1. QueryStream#destroy([err])

Destroys the stream, closing the underlying cursor, which emits the close event. No more events will be emitted after the close event.

参数:
源码
QueryStream.prototype.destroy = function(err) {
  if (this._destroyed) {
    return;
  }
  this._destroyed = true;
  this._running = false;
  this.readable = false;

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

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

  this.emit('close');
};

19.2. QueryStream#pause()

Pauses this stream.

源码
QueryStream.prototype.pause = function() {
  this.paused = true;
};

19.3. QueryStream#pipe()

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

参见:
示例:
query.stream().pipe(writeStream [, options])

19.4. QueryStream(query, [options])

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

参数:
继承:
事件:
  • 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.

var stream = Model.find().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
});

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

Model.where('created').gte(twoWeeksAgo).stream().pipe(writeStream);
可用选项:
  • transform: optional function which accepts a mongoose document. The return value of the function will be emitted on data.
示例:
// JSON.stringify all documents before emitting
var stream = Thing.find().stream({ transform: JSON.stringify });
stream.pipe(writeStream);
注意:

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.

注意:

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.

源码
function QueryStream(query, options) {
  Stream.call(this);

  this.query = query;
  this.readable = true;
  this.paused = false;
  this._cursor = null;
  this._destroyed = null;
  this._fields = null;
  this._buffer = null;
  this._inline = T_INIT;
  this._running = false;
  this._transform = options && typeof options.transform === 'function'
      ? options.transform
      : K;

  // give time to hook up events
  var _this = this;
  process.nextTick(function() {
    _this._init();
  });
}

19.5. QueryStream#resume()

Resumes this stream.

源码
QueryStream.prototype.resume = function() {
  this.paused = false;

  if (!this._cursor) {
    // cannot start if not initialized
    return;
  }

  // are we within the trampoline?
  if (T_INIT === this._inline) {
    return;
  }

  if (!this._running) {
    // outside QueryStream control, need manual restart
    return this._next();
  }
};

19.6. QueryStream#paused

Flag stating whether or not this stream is paused.

源码
QueryStream.prototype.paused;

// trampoline flags
var T_INIT = 0;
var T_IDLE = 1;
var T_CONT = 2;

19.7. QueryStream#readable

Flag stating whether or not this stream is readable.

源码
QueryStream.prototype.readable;

20. services/cursor/eachAsync.js

源码:services/cursor/eachAsync.js

20.1. module.exports(next, fn, options, [callback])

Execute fn for every document in the cursor. If fn returns a promise, will wait for the promise to resolve before iterating on to the next one. Returns a promise that resolves when done.

参数:
  • next <Function> the thunk to call to get the next document

  • fn <Function>

  • options <Object>

  • [callback] <Function> executed when all docs have been processed

返回值:

21. error/index.js

源码:error/index.js

21.1. MongooseError(msg)

MongooseError constructor

参数:
继承:
源码
function MongooseError(msg) {
  Error.call(this);
  if (Error.captureStackTrace) {
    Error.captureStackTrace(this);
  } else {
    this.stack = new Error().stack;
  }
  this.message = msg;
  this.name = 'MongooseError';
}

21.2. MongooseError.DocumentNotFoundError

This error will be called when save() fails because the underlying document was not found. The constructor takes one parameter, the conditions that mongoose passed to update() when trying to update the document.

源码
MongooseError.DocumentNotFoundError = require('./notFound');

21.3. MongooseError.messages

The default built-in validator error messages.

源码
MongooseError.messages = require('./messages');

// backward compat
MongooseError.Messages = MongooseError.messages;
参见:

22. error/messages.js

源码:error/messages.js

22.1. MongooseError.messages()

默认的验证器错误消息。可以进行自定义。

源码
var msg = module.exports = exports = {};

msg.DocumentNotFoundError = null;

msg.general = {};
msg.general.default = 'Validator failed for path `{PATH}` with value `{VALUE}`';
msg.general.required = 'Path `{PATH}` is required.';

msg.Number = {};
msg.Number.min = 'Path `{PATH}` ({VALUE}) is less than minimum allowed value ({MIN}).';
msg.Number.max = 'Path `{PATH}` ({VALUE}) is more than maximum allowed value ({MAX}).';

msg.Date = {};
msg.Date.min = 'Path `{PATH}` ({VALUE}) is before minimum allowed value ({MIN}).';
msg.Date.max = 'Path `{PATH}` ({VALUE}) is after maximum allowed value ({MAX}).';

msg.String = {};
msg.String.enum = '`{VALUE}` is not a valid enum value for path `{PATH}`.';
msg.String.match = 'Path `{PATH}` is invalid ({VALUE}).';
msg.String.minlength = 'Path `{PATH}` (`{VALUE}`) is shorter than the minimum allowed length ({MINLENGTH}).';
msg.String.maxlength = 'Path `{PATH}` (`{VALUE}`) is longer than the maximum allowed length ({MAXLENGTH}).';
// 在每个模式或全局范围内进行自定义
var mongoose = require('mongoose');
mongoose.Error.messages.String.enum  = "Your custom message for {PATH}.";

正如您可能已经注意到的,错误消息支持基本的模板

  • {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

点击上面的源码,可以看到所有的默认值。


23. error/validation.js

源码:error/validation.js

23.1. ValidationError#toString()

Console.log helper

源码
ValidationError.prototype.toString = function() {
  return this.name + ': ' + _generateMessage(this);
};

24. model.js

源码:model.js

24.1. Model#$where(argument)

Creates a Query and specifies a $where condition.

参数:
  • argument <String, Function>is a javascript string or anonymous function
返回值:
参见:

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.username.indexOf("val") !== -1').exec(function (err, docs) {});

24.2. Model#increment()

Signal that we desire an increment of this documents version.

参见:
示例:
Model.findById(id, function (err, doc) {
  doc.increment();
  doc.save(function (err) { .. })
})
源码
Model.prototype.increment = function increment() {
  this.$__.version = VERSION_ALL;
  return this;
};

24.3. Model#model(name)

Returns another Model instance.

参数:
示例:
var doc = new Tank;
doc.model('User').findById(id, callback);
源码
Model.prototype.model = function model(name) {
  return this.db.model(name);
};

24.4. Model(doc)

Model constructor

参数:
  • doc <Object> values with which to create the document
继承:
事件:
  • error: If listening to this event, 'error' 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.

  • index-single-start: Emitted when an individual index starts within Model#ensureIndexes. The fields and options being used to build the index are also passed with the event.

  • index-single-done: Emitted when an individual index finishes within Model#ensureIndexes. If an error occurred it is passed with the event. The fields, options, and index name are also passed.

Provides the interface to MongoDB collections as well as creates document instances.

源码
function Model(doc, fields, skipId) {
  if (fields instanceof Schema) {
    throw new TypeError('2nd argument to `Model` must be a POJO or string, ' +
      '**not** a schema. Make sure you\'re calling `mongoose.model()`, not ' +
      '`mongoose.Model()`.');
  }
  Document.call(this, doc, fields, skipId, true);
}

24.5. Model#remove([fn])

Removes this document from the db.

参数:
  • [fn] optional callback
返回值:
示例:
product.remove(function (err, product) {
  if (err) return handleError(err);
  Product.findById(product._id, function (err, product) {
    console.log(product) // null
  })
})

As an extra measure of flow control, remove will return a Promise (bound to fn if passed) so it could be chained, or hooked to recive errors

示例:
product.remove().then(function (product) {
   ...
}).catch(function (err) {
   assert.ok(err)
})
源码
Model.prototype.remove = function remove(options, fn) {
  if (typeof options === 'function') {
    fn = options;
    options = undefined;
  }

  var _this = this;

  if (!options) {
    options = {};
  }

  if (this.$__.removing) {
    if (fn) {
      this.$__.removing.then(
          function(res) { fn(null, res); },
          function(err) { fn(err); });
    }
    return this;
  }
  if (this.$__.isDeleted) {
    setImmediate(function() {
      fn(null, _this);
    });
    return this;
  }

  var Promise = PromiseProvider.get();

  if (fn) {
    fn = this.constructor.$wrapCallback(fn);
  }

  this.$__.removing = new Promise.ES6(function(resolve, reject) {
    var where = _this.$__where();
    if (where instanceof Error) {
      reject(where);
      fn && fn(where);
      return;
    }

    if (!options.safe && _this.schema.options.safe) {
      options.safe = _this.schema.options.safe;
    }

    _this.collection.remove(where, options, function(err) {
      if (!err) {
        _this.$__.isDeleted = true;
        _this.emit('remove', _this);
        _this.constructor.emit('remove', _this);
        resolve(_this);
        fn && fn(null, _this);
        return;
      }
      _this.$__.isDeleted = false;
      reject(err);
      fn && fn(err);
    });
  });
  return this.$__.removing;
};

24.6. Model#save([options], [options.safe], [options.validateBeforeSave], [fn])

Saves this document.

参数:
  • [options] <Object> options optional options

  • [options.safe] <Object> overrides schema's safe option

  • [options.validateBeforeSave] <Boolean> set to false to save without validating.

  • [fn] <Function> optional callback

返回值:
参见:
示例:
product.sold = Date.now();
product.save(function (err, product, numAffected) {
  if (err) ..
})

The callback will receive three parameters

  • err if an error occurred
  • product which is the saved product
  • numAffected will be 1 when the document was successfully persisted to MongoDB, otherwise 0. Unless you tweak mongoose's internals, you don't need to worry about checking this parameter for errors - checking err is sufficient to make sure your document was properly saved.

As an extra measure of flow control, save will return a Promise.

示例:
product.save().then(function(product) {
   ...
});

For legacy reasons, mongoose stores object keys in reverse order on initial save. That is, { a: 1, b: 2 } will be saved as { b: 2, a: 1 } in MongoDB. To override this behavior, set the toObject.retainKeyOrder option to true on your schema.

源码
Model.prototype.save = function(options, fn) {
  if (typeof options === 'function') {
    fn = options;
    options = undefined;
  }

  if (!options) {
    options = {};
  }

  if (fn) {
    fn = this.constructor.$wrapCallback(fn);
  }

  return this.$__save(options, fn);
};

24.7. Model.aggregate([...], [callback])

Performs aggregations on the models collection.

源码
Model.aggregate = function aggregate() {
  var args = [].slice.call(arguments),
      aggregate,
      callback;

  if (typeof args[args.length - 1] === 'function') {
    callback = args.pop();
  }

  if (args.length === 1 && util.isArray(args[0])) {
    aggregate = new Aggregate(args[0]);
  } else {
    aggregate = new Aggregate(args);
  }

  aggregate.model(this);

  if (typeof callback === 'undefined') {
    return aggregate;
  }

  if (callback) {
    callback = this.$wrapCallback(callback);
  }

  aggregate.exec(callback);
};
参数:
  • [...] aggregation pipeline operator(s) or operator array

  • [callback] <Function>

返回值:
参见:

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.

This function does not trigger any middleware.

示例:
// 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 } ]
});
注意:
  • 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

24.8. Model.bulkWrite(ops, [options], [callback])

Sends multiple insertOne, updateOne, updateMany, replaceOne, deleteOne, and/or deleteMany operations to the MongoDB server in one command. This is faster than sending multiple independent operations (like) if you use create()) because with bulkWrite() there is only one round trip to MongoDB.

源码
Model.bulkWrite = function(ops, options, callback) {
  var Promise = PromiseProvider.get();
  var _this = this;
  if (typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (callback) {
    callback = this.$wrapCallback(callback);
  }
  options = options || {};

  var validations = ops.map(function(op) {
    if (op['insertOne']) {
      return function(callback) {
        op['insertOne']['document'] = new _this(op['insertOne']['document']);
        op['insertOne']['document'].validate({ __noPromise: true }, function(error) {
          if (error) {
            return callback(error);
          }
          callback(null);
        });
      };
    } else if (op['updateOne']) {
      op = op['updateOne'];
      return function(callback) {
        try {
          op['filter'] = cast(_this.schema, op['filter']);
          op['update'] = castUpdate(_this.schema, op['update'],
            _this.schema.options.strict);
          if (op.setDefaultsOnInsert) {
            setDefaultsOnInsert(op['filter'], _this.schema, op['update'], {
              setDefaultsOnInsert: true,
              upsert: op.upsert
            });
          }
        } catch (error) {
          return callback(error);
        }

        callback(null);
      };
    } else if (op['updateMany']) {
      op = op['updateMany'];
      return function(callback) {
        try {
          op['filter'] = cast(_this.schema, op['filter']);
          op['update'] = castUpdate(_this.schema, op['update'], {
            strict: _this.schema.options.strict,
            overwrite: false
          });
          if (op.setDefaultsOnInsert) {
            setDefaultsOnInsert(op['filter'], _this.schema, op['update'], {
              setDefaultsOnInsert: true,
              upsert: op.upsert
            });
          }
        } catch (error) {
          return callback(error);
        }

        callback(null);
      };
    } else if (op['replaceOne']) {
      return function(callback) {
        try {
          op['replaceOne']['filter'] = cast(_this.schema,
            op['replaceOne']['filter']);
        } catch (error) {
          return callback(error);
        }

        // set `skipId`, otherwise we get "_id field cannot be changed"
        op['replaceOne']['replacement'] =
          new _this(op['replaceOne']['replacement'], null, true);
        op['replaceOne']['replacement'].validate({ __noPromise: true }, function(error) {
          if (error) {
            return callback(error);
          }
          callback(null);
        });
      };
    } else if (op['deleteOne']) {
      return function(callback) {
        try {
          op['deleteOne']['filter'] = cast(_this.schema,
            op['deleteOne']['filter']);
        } catch (error) {
          return callback(error);
        }

        callback(null);
      };
    } else if (op['deleteMany']) {
      return function(callback) {
        try {
          op['deleteMany']['filter'] = cast(_this.schema,
            op['deleteMany']['filter']);
        } catch (error) {
          return callback(error);
        }

        callback(null);
      };
    } else {
      return function(callback) {
        callback(new Error('Invalid op passed to `bulkWrite()`'));
      };
    }
  });

  var promise = new Promise.ES6(function(resolve, reject) {
    parallel(validations, function(error) {
      if (error) {
        callback && callback(error);
        return reject(error);
      }

      _this.collection.bulkWrite(ops, options, function(error, res) {
        if (error) {
          callback && callback(error);
          return reject(error);
        }

        callback && callback(null, res);
        resolve(res);
      });
    });
  });

  return promise;
};
参数:
  • ops <Array>

  • [options] <Object>

  • [callback] <Function> callback function(error, bulkWriteOpResult) {}

返回值:
  • <Promise> resolves to a BulkWriteOpResult if the operation succeeds
参见:

Mongoose will perform casting on all operations you provide.

This function does not trigger any middleware, not save() nor update(). If you need to trigger save() middleware for every document use create() instead.

示例:
Character.bulkWrite([
  {
    insertOne: {
      document: {
        name: 'Eddard Stark',
        title: 'Warden of the North'
      }
    }
  },
  {
    updateOne: {
      filter: { name: 'Eddard Stark' },
      // If you were using the MongoDB driver directly, you'd need to do
      // `update: { $set: { title: ... } }` but mongoose adds $set for
      // you.
      update: { title: 'Hand of the King' }
    }
  },
  {
    deleteOne: {
      {
        filter: { name: 'Eddard Stark' }
      }
    }
  }
]).then(handleResult);

24.9. Model.count(conditions, [callback])

计算在数据库集合中匹配的文档数量。

源码
Model.count = function count(conditions, callback) {
  if (typeof conditions === 'function') {
    callback = conditions;
    conditions = {};
  }

  // get the mongodb collection object
  var mq = new this.Query({}, {}, this, this.collection);

  if (callback) {
    callback = this.$wrapCallback(callback);
  }

  return mq.count(conditions, callback);
};
参数:
返回值:
示例:
Adventure.count({ type: 'jungle' }, function (err, count) {
  if (err) ..
  console.log('there are %d jungle adventures', count);
});

24.10. Model.create(doc(s), [callback])

将一个或多个文档保存到数据库的快捷方式。MyModel.create(docs) 会为 docs 参数中的每一个文档执行 new MyModel(doc).save()

源码
Model.create = function create(doc, callback) {
  var args;
  var cb;
  var discriminatorKey = this.schema.options.discriminatorKey;

  if (Array.isArray(doc)) {
    args = doc;
    cb = callback;
  } else {
    var last = arguments[arguments.length - 1];
    // Handle falsy callbacks re: #5061
    if (typeof last === 'function' || !last) {
      cb = last;
      args = utils.args(arguments, 0, arguments.length - 1);
    } else {
      args = utils.args(arguments);
    }
  }

  var Promise = PromiseProvider.get();
  var _this = this;
  if (cb) {
    cb = this.$wrapCallback(cb);
  }

  var promise = new Promise.ES6(function(resolve, reject) {
    if (args.length === 0) {
      setImmediate(function() {
        cb && cb(null);
        resolve(null);
      });
      return;
    }

    var toExecute = [];
    var firstError;
    args.forEach(function(doc) {
      toExecute.push(function(callback) {
        var Model = _this.discriminators && doc[discriminatorKey] ?
          _this.discriminators[doc[discriminatorKey]] :
          _this;
        var toSave = doc;
        var callbackWrapper = function(error, doc) {
          if (error) {
            if (!firstError) {
              firstError = error;
            }
            return callback(null, { error: error });
          }
          callback(null, { doc: doc });
        };

        if (!(toSave instanceof Model)) {
          try {
            toSave = new Model(toSave);
          } catch (error) {
            return callbackWrapper(error);
          }
        }

        // Hack to avoid getting a promise because of
        // $__registerHooksFromSchema
        if (toSave.$__original_save) {
          toSave.$__original_save({ __noPromise: true }, callbackWrapper);
        } else {
          toSave.save({ __noPromise: true }, callbackWrapper);
        }
      });
    });

    parallel(toExecute, function(error, res) {
      var savedDocs = [];
      var len = res.length;
      for (var i = 0; i < len; ++i) {
        if (res[i].doc) {
          savedDocs.push(res[i].doc);
        }
      }

      if (firstError) {
        if (cb) {
          cb(firstError, savedDocs);
        } else {
          reject(firstError);
        }
        return;
      }

      if (doc instanceof Array) {
        resolve(savedDocs);
        cb && cb.call(_this, null, savedDocs);
      } else {
        resolve.apply(promise, savedDocs);
        if (cb) {
          cb.apply(_this, [null].concat(savedDocs));
        }
      }
    });
  });

  return promise;
};
参数:
返回值:

该函数触发以下中间件

  • save()
示例:
// 传递单个文档
Candy.create({ type: 'jelly bean' }, { type: 'snickers' }, function (err, jellybean, snickers) {
  if (err) // ...
});

// 传递一个数组
var array = [{ type: 'jelly bean' }, { type: 'snickers' }];
Candy.create(array, function (err, candies) {
  if (err) // ...

  var jellybean = candies[0];
  var snickers = candies[1];
  // ...
});

// 回调是可选的;如果你喜欢的话,可以使用返回的 promise:
var promise = Candy.create({ type: 'jawbreaker' });
promise.then(function (jawbreaker) {
  // ...
})

24.11. Model.createIndexes([options], [cb])

Similar to ensureIndexes(), except for it uses the createIndex function. The ensureIndex() function checks to see if an index with that name already exists, and, if not, does not attempt to create the index. createIndex() bypasses this check.

源码
Model.createIndexes = function createIndexes(options, callback) {
  if (typeof options === 'function') {
    callback = options;
    options = {};
  }
  options = options || {};
  options.createIndex = true;
  return this.ensureIndexes(options, callback);
};

function _ensureIndexes(model, options, callback) {
  var indexes = model.schema.indexes();
  options = options || {};

  var done = function(err) {
    if (err && model.schema.options.emitIndexErrors) {
      model.emit('error', err);
    }
    model.emit('index', err);
    callback && callback(err);
  };

  if (!indexes.length) {
    setImmediate(function() {
      done();
    });
    return;
  }
  // Indexes are created one-by-one to support how MongoDB < 2.4 deals
  // with background indexes.

  var indexSingleDone = function(err, fields, options, name) {
    model.emit('index-single-done', err, fields, options, name);
  };
  var indexSingleStart = function(fields, options) {
    model.emit('index-single-start', fields, options);
  };

  var create = function() {
    if (options._automatic) {
      if (model.schema.options.autoIndex === false ||
          (model.schema.options.autoIndex == null && model.db.config.autoIndex === false)) {
        return done();
      }
    }

    var index = indexes.shift();
    if (!index) return done();

    var indexFields = index[0];
    var indexOptions = index[1];
    _handleSafe(options);

    indexSingleStart(indexFields, options);
    var methodName = options.createIndex ? 'createIndex' : 'ensureIndex';
    model.collection[methodName](indexFields, indexOptions, utils.tick(function(err, name) {
      indexSingleDone(err, indexFields, indexOptions, name);
      if (err) {
        return done(err);
      }
      create();
    }));
  };

  setImmediate(function() {
    // If buffering is off, do this manually.
    if (options._automatic && !model.collection.collection) {
      model.collection.addQueue(create, []);
    } else {
      create();
    }
  });
}

function _handleSafe(options) {
  if (options.safe) {
    if (typeof options.safe === 'boolean') {
      options.w = options.safe;
      delete options.safe;
    }
    if (typeof options.safe === 'object') {
      options.w = options.safe.w;
      options.j = options.safe.j;
      options.wtimeout = options.safe.wtimeout;
      delete options.safe;
    }
  }
}
参数:
  • [options]<Object> internal options

  • [cb] <Function> optional callback

返回值:

24.12. Model.deleteMany(conditions, [callback])

Deletes all of the documents that match conditions from the collection. Behaves like remove(), but deletes all documents that match conditions regardless of the single option.

源码
Model.deleteMany = function deleteMany(conditions, callback) {
  if (typeof conditions === 'function') {
    callback = conditions;
    conditions = {};
  }

  // get the mongodb collection object
  var mq = new this.Query(conditions, {}, this, this.collection);

  if (callback) {
    callback = this.$wrapCallback(callback);
  }

  return mq.deleteMany(callback);
};
参数:
返回值:
示例:
Character.deleteMany({ name: /Stark/, age: { $gte: 18 } }, function (err) {});
注意:

Like Model.remove(), this function does not trigger pre('remove') or post('remove') hooks.

24.13. Model.deleteOne(conditions, [callback])

删除集合中与 conditions(条件) 相匹配的第一个文档。 就像 remove() 一样,但是最多只能删除一个文件,而不管 single 选项。

源码
Model.deleteOne = function deleteOne(conditions, callback) {
  if (typeof conditions === 'function') {
    callback = conditions;
    conditions = {};
  }

  // get the mongodb collection object
  var mq = new this.Query(conditions, {}, this, this.collection);

  if (callback) {
    callback = this.$wrapCallback(callback);
  }

  return mq.deleteOne(callback);
};
参数:
返回值:
示例:
Character.deleteOne({ name: 'Eddard Stark' }, function (err) {});
注意:

Like Model.remove(), this function does not trigger pre('remove') or post('remove') hooks.

24.14. Model.discriminator(name, schema)

Adds a discriminator type.

源码
Model.discriminator = function(name, schema) {
  var model;
  if (typeof name === 'function') {
    model = name;
    name = utils.getFunctionName(model);
    if (!(model.prototype instanceof Model)) {
      throw new Error('The provided class ' + name + ' must extend Model');
    }
  }

  schema = discriminator(this, name, schema);
  if (this.db.models[name]) {
    throw new OverwriteModelError(name);
  }

  schema.$isRootDiscriminator = true;

  model = this.db.model(model || name, schema, this.collection.name);
  this.discriminators[name] = model;
  var d = this.discriminators[name];
  d.prototype.__proto__ = this.prototype;
  Object.defineProperty(d, 'baseModelName', {
    value: this.modelName,
    configurable: true,
    writable: false
  });

  // apply methods and statics
  applyMethods(d, schema);
  applyStatics(d, schema);

  return d;
};

// Model (class) features
参数:
  • name <String> discriminator model name

  • schema discriminator model schema

示例:
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);

24.15. Model.distinct(field, [conditions], [callback])

Creates a Query for a distinct operation.

源码
Model.distinct = function distinct(field, conditions, callback) {
  // get the mongodb collection object
  var mq = new this.Query({}, {}, this, this.collection);

  if (typeof conditions === 'function') {
    callback = conditions;
    conditions = {};
  }
  if (callback) {
    callback = this.$wrapCallback(callback);
  }

  return mq.distinct(field, conditions, callback);
};
参数:
返回值:

Passing a callback immediately executes the query.

示例:
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);

24.16. Model.ensureIndexes([options], [cb])

Sends createIndex commands to mongo for each index declared in the schema. The createIndex commands are sent in series.

源码
Model.ensureIndexes = function ensureIndexes(options, callback) {
  if (typeof options === 'function') {
    callback = options;
    options = null;
  }

  if (options && options.__noPromise) {
    _ensureIndexes(this, options, callback);
    return;
  }

  if (callback) {
    callback = this.$wrapCallback(callback);
  }

  var _this = this;
  var Promise = PromiseProvider.get();
  return new Promise.ES6(function(resolve, reject) {
    _ensureIndexes(_this, options || {}, function(error) {
      if (error) {
        callback && callback(error);
        reject(error);
      }
      callback && callback();
      resolve();
    });
  });
};
参数:
  • [options] <Object> internal options

  • [cb] <Function> optional callback

返回值:
示例:
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.

示例:
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
})
注意:

It is not recommended that you run this in production. Index creation may impact database performance depending on your load. Use with caution.

24.17. Model.find(conditions, [projection], [options], [callback])

查找文档

源码
Model.find = function find(conditions, projection, options, callback) {
  if (typeof conditions === 'function') {
    callback = conditions;
    conditions = {};
    projection = null;
    options = null;
  } else if (typeof projection === 'function') {
    callback = projection;
    projection = null;
    options = null;
  } else if (typeof options === 'function') {
    callback = options;
    options = null;
  }

  var mq = new this.Query({}, {}, this, this.collection);
  mq.select(projection);
  mq.setOptions(options);
  if (this.schema.discriminatorMapping &&
      this.schema.discriminatorMapping.isRoot &&
      mq.selectedInclusively()) {
    // Need to select discriminator key because original schema doesn't have it
    mq.select(this.schema.options.discriminatorKey);
  }

  if (callback) {
    callback = this.$wrapCallback(callback);
  }

  return mq.find(conditions, callback);
};
参数:
返回值:
参见:

在命令被发送之前,conditions 被转换为它们各自的 SchemaTypes。

示例:
// name 为 john 且 大于等于 18岁
MyModel.find({ name: 'john', age: { $gte: 18 }});

// 立即执行, 奖结果传递给回调
MyModel.find({ name: 'john', age: { $gte: 18 }}, function (err, docs) {});

// name 像 john 并且只选择  "name" 和 "friends" 字段, 立即执行
MyModel.find({ name: /john/i }, 'name friends', function (err, docs) { })

// 传递选项对象
MyModel.find({ name: /john/i }, null, { skip: 10 })

// 传递选项对象并立即执行
MyModel.find({ name: /john/i }, null, { skip: 10 }, function (err, docs) {});

// 显式地执行一个查询
var query = MyModel.find({ name: /john/i }, null, { skip: 10 })
query.exec(function (err, docs) {});

// 使用执行查询返回的 promise
var query = MyModel.find({ name: /john/i }, null, { skip: 10 });
var promise = query.exec();
promise.addBack(function (err, docs) {});

24.18. Model.findById(id, [projection], [options], [callback])

Finds a single document by its _id field. findById(id) is almost* equivalent to findOne({ _id: id }). If you want to query by a document's _id, use findById() instead of findOne().

源码
Model.findById = function findById(id, projection, options, callback) {
  if (typeof id === 'undefined') {
    id = null;
  }

  if (callback) {
    callback = this.$wrapCallback(callback);
  }

  return this.findOne({_id: id}, projection, options, callback);
};
参数:
返回值:
参见:

The id is cast based on the Schema before sending the command.

该函数触发以下中间件

  • findOne()
  • Except for how it treats undefined. If you use findOne(), you'll see that findOne(undefined) and findOne({ _id: undefined }) are equivalent to findOne({}) and return arbitrary documents. However, mongoose translates findById(undefined) into findOne({ _id: null }).
示例:
// 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) {});

24.19. Model.findByIdAndRemove(id, [options], [callback])

Issue a mongodb findAndModify remove command by a document's _id field. findByIdAndRemove(id, ...) is equivalent to findOneAndRemove({ _id: id }, ...).

源码
Model.findByIdAndRemove = function(id, options, callback) {
  if (arguments.length === 1 && typeof id === 'function') {
    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);
  }
  if (callback) {
    callback = this.$wrapCallback(callback);
  }

  return this.findOneAndRemove({_id: id}, options, callback);
};
参数:
返回值:
参见:

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.

该函数触发以下中间件

  • findOneAndRemove()
选项:
  • 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
  • passRawResult: if true, passes the raw result from the MongoDB driver as the third callback parameter
  • strict: overwrites the schema's strict mode option for this update
示例:
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

24.20. Model.findByIdAndUpdate(id, [update], [options], [callback])

Issues a mongodb findAndModify update command by a document's _id field. findByIdAndUpdate(id, ...) is equivalent to findOneAndUpdate({ _id: id }, ...).

源码
Model.findByIdAndUpdate = function(id, update, options, callback) {
  if (callback) {
    callback = this.$wrapCallback(callback);
  }
  if (arguments.length === 1) {
    if (typeof id === 'function') {
      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);
  }

  // if a model is passed in instead of an id
  if (id instanceof Document) {
    id = id._id;
  }

  return this.findOneAndUpdate.call(this, {_id: id}, update, options, callback);
};
参数:
返回值:

<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.

该函数触发以下中间件

  • findOneAndUpdate()
选项:
  • new: bool - true to return the modified document rather than the original. defaults to false
  • upsert: bool - creates the object if it doesn't exist. defaults to false.
  • runValidators: 如果 true,在此命令上运行更新验证器。更新验证器根据模型的模式的定义验证更新操作。
  • setDefaultsOnInsert: if this and upsert are true, mongoose will apply the defaults specified in the model's schema if a new document is created. This option only works on MongoDB >= 2.4 because it relies on MongoDB 的 $setOnInsert 操作符。.
  • 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
  • passRawResult: if true, passes the raw result from the MongoDB driver as the third callback parameter
  • strict: overwrites the schema's strict mode option for this update
  • runSettersOnQuery: bool - if true, run all setters defined on the associated model's schema for all fields defined in the query and the update.
    示例:
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
注意:

All top level update keys which are not atomic operation names are treated as set operations:

示例:
Model.findByIdAndUpdate(id, { name: 'jason bourne' }, options, callback)

// is sent as
Model.findByIdAndUpdate(id, { $set: { name: 'jason bourne' }}, options, callback)

This helps prevent accidentally overwriting your document with { name: 'jason bourne' }.

注意:

Values are cast to their appropriate types when using the findAndModify helpers. However, the below are not executed by default.

  • defaults. Use the setDefaultsOnInsert option to override.
  • setters. Use the runSettersOnQuery option to override.

findAndModify helpers support limited validation. You can enable these by setting the runValidators options, respectively.

If you need full-fledged validation, use the traditional approach of first retrieving the document.

Model.findById(id, function (err, doc) {
  if (err) ..
  doc.name = 'jason bourne';
  doc.save(callback);
});

24.21. Model.findOne([conditions], [projection], [options], [callback])

Finds one document.

源码
Model.findOne = function findOne(conditions, projection, options, callback) {
  if (typeof options === 'function') {
    callback = options;
    options = null;
  } else if (typeof projection === 'function') {
    callback = projection;
    projection = null;
    options = null;
  } else if (typeof conditions === 'function') {
    callback = conditions;
    conditions = {};
    projection = null;
    options = null;
  }

  // get the mongodb collection object
  var mq = new this.Query({}, {}, this, this.collection);
  mq.select(projection);
  mq.setOptions(options);
  if (this.schema.discriminatorMapping &&
      this.schema.discriminatorMapping.isRoot &&
      mq.selectedInclusively()) {
    mq.select(this.schema.options.discriminatorKey);
  }

  if (callback) {
    callback = this.$wrapCallback(callback);
  }

  return mq.findOne(conditions, callback);
};
参数:
返回值:
参见:

The conditions are cast to their respective SchemaTypes before the command is sent.

注意:

conditions is optional, and if conditions is null or undefined, mongoose will send an empty findOne command to MongoDB, which will return an arbitrary document. If you're querying by _id, use findById() instead.

示例:
// 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);

24.22. Model.findOneAndRemove(conditions, [options], [callback])

Issue a mongodb findAndModify remove command.

源码
Model.findOneAndRemove = function(conditions, options, callback) {
  if (arguments.length === 1 && typeof conditions === 'function') {
    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 (typeof options === 'function') {
    callback = options;
    options = undefined;
  }
  if (callback) {
    callback = this.$wrapCallback(callback);
  }

  var fields;
  if (options) {
    fields = options.select;
    options.select = undefined;
  }

  var mq = new this.Query({}, {}, this, this.collection);
  mq.select(fields);

  return mq.findOneAndRemove(conditions, options, callback);
};
参数:
返回值:
参见:

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.

该函数触发以下中间件

  • findOneAndRemove()
选项:
  • sort: if multiple docs are found by the conditions, sets the sort order to choose which doc to update
  • maxTimeMS: puts a time limit on the query - requires mongodb >= 2.6.0
  • select: sets the document fields to return
  • passRawResult: if true, passes the raw result from the MongoDB driver as the third callback parameter
  • strict: overwrites the schema's strict mode option for this update
示例:
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

Values are cast to their appropriate types when using the findAndModify helpers. However, the below are not executed by default.

  • defaults. Use the setDefaultsOnInsert option to override.
  • setters. Use the runSettersOnQuery option to override.

findAndModify helpers support limited validation. You can enable these by setting the runValidators options, respectively.

If you need full-fledged validation, use the traditional approach of first retrieving the document.

Model.findById(id, function (err, doc) {
  if (err) ..
  doc.name = 'jason bourne';
  doc.save(callback);
});

24.23. Model.findOneAndUpdate([conditions], [update], [options], [callback])

Issues a mongodb findAndModify update command.

源码
Model.findOneAndUpdate = function(conditions, update, options, callback) {
  if (typeof options === 'function') {
    callback = options;
    options = null;
  } else if (arguments.length === 1) {
    if (typeof conditions === 'function') {
      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;
  }
  if (callback) {
    callback = this.$wrapCallback(callback);
  }

  var fields;
  if (options && options.fields) {
    fields = options.fields;
  }

  update = utils.clone(update, {depopulate: 1, _isNested: true});
  if (this.schema.options.versionKey && options && options.upsert) {
    if (options.overwrite) {
      update[this.schema.options.versionKey] = 0;
    } else {
      if (!update.$setOnInsert) {
        update.$setOnInsert = {};
      }
      update.$setOnInsert[this.schema.options.versionKey] = 0;
    }
  }

  var mq = new this.Query({}, {}, this, this.collection);
  mq.select(fields);

  return mq.findOneAndUpdate(conditions, update, options, callback);
};
参数:
返回值:
参见:

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.

选项:
  • new: bool - if true, return the modified document rather than the original. defaults to false (changed in 4.0)
  • upsert: bool - creates the object if it doesn't exist. defaults to false.
  • fields: {Object|String} - Field selection. Equivalent to .select(fields).findOneAndUpdate()
  • maxTimeMS: puts a time limit on the query - requires mongodb >= 2.6.0
  • sort: if multiple docs are found by the conditions, sets the sort order to choose which doc to update
  • runValidators: 如果 true,在此命令上运行更新验证器。更新验证器根据模型的模式的定义验证更新操作。
  • setDefaultsOnInsert: if this and upsert are true, mongoose will apply the defaults specified in the model's schema if a new document is created. This option only works on MongoDB >= 2.4 because it relies on MongoDB 的 $setOnInsert 操作符。.
  • passRawResult: if true, passes the raw result from the MongoDB driver as the third callback parameter
  • strict: overwrites the schema's strict mode option for this update
  • runSettersOnQuery: bool - if true, run all setters defined on the associated model's schema for all fields defined in the query and the update.
示例:
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
注意:

All top level update keys which are not atomic operation names are treated as set operations:

示例:
var query = { name: 'borne' };
Model.findOneAndUpdate(query, { name: 'jason bourne' }, options, callback)

// is sent as
Model.findOneAndUpdate(query, { $set: { name: 'jason bourne' }}, options, callback)

This helps prevent accidentally overwriting your document with { name: 'jason bourne' }.

注意:

Values are cast to their appropriate types when using the findAndModify helpers. However, the below are not executed by default.

  • defaults. Use the setDefaultsOnInsert option to override.
  • setters. Use the runSettersOnQuery option to override.

findAndModify helpers support limited validation. You can enable these by setting the runValidators options, respectively.

If you need full-fledged validation, use the traditional approach of first retrieving the document.

Model.findById(id, function (err, doc) {
  if (err) ..
  doc.name = 'jason bourne';
  doc.save(callback);
});

24.24. Model.geoNear(GeoJSON, options, [callback])

geoNear support for Mongoose

源码
Model.geoNear = function(near, options, callback) {
  if (typeof options === 'function') {
    callback = options;
    options = {};
  }

  if (callback) {
    callback = this.$wrapCallback(callback);
  }

  var _this = this;
  var Promise = PromiseProvider.get();
  if (!near) {
    return new Promise.ES6(function(resolve, reject) {
      var error = new Error('Must pass a near option to geoNear');
      reject(error);
      callback && callback(error);
    });
  }

  var x;
  var y;
  var schema = this.schema;

  return new Promise.ES6(function(resolve, reject) {
    var handler = function(err, res) {
      if (err) {
        reject(err);
        callback && callback(err);
        return;
      }
      if (options.lean) {
        resolve(res.results, res.stats);
        callback && callback(null, res.results, res.stats);
        return;
      }

      var count = res.results.length;
      // if there are no results, fulfill the promise now
      if (count === 0) {
        resolve(res.results, res.stats);
        callback && callback(null, res.results, res.stats);
        return;
      }

      var errSeen = false;

      function init(err) {
        if (err && !errSeen) {
          errSeen = true;
          reject(err);
          callback && callback(err);
          return;
        }
        if (--count <= 0) {
          resolve(res.results, res.stats);
          callback && callback(null, res.results, res.stats);
        }
      }

      for (var i = 0; i < res.results.length; i++) {
        var temp = res.results[i].obj;
        res.results[i].obj = new _this();
        res.results[i].obj.init(temp, init);
      }
    };

    if (options.query != null) {
      options.query = utils.clone(options.query, { retainKeyOrder: 1 });
      cast(schema, options.query);
    }

    if (Array.isArray(near)) {
      if (near.length !== 2) {
        var error = new Error('If using legacy coordinates, must be an array ' +
            'of size 2 for geoNear');
        reject(error);
        callback && callback(error);
        return;
      }
      x = near[0];
      y = near[1];
      _this.collection.geoNear(x, y, options, handler);
    } else {
      if (near.type !== 'Point' || !Array.isArray(near.coordinates)) {
        error = new Error('Must pass either a legacy coordinate array or ' +
            'GeoJSON Point to geoNear');
        reject(error);
        callback && callback(error);
        return;
      }

      _this.collection.geoNear(near, options, handler);
    }
  });
};
参数:
  • GeoJSON point or legacy coordinate pair [x,y] to search near

  • options <Object> for the query

  • [callback] <Function> optional callback for the query

返回值:
参见:

This function does not trigger any middleware. In particular, this bypasses find() middleware.

选项:

lean {Boolean} return the raw object All options supported by the driver are also supported

示例:
// 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);
});

24.25. Model.geoSearch(conditions, options, [callback])

Implements $geoSearch functionality for Mongoose

源码
Model.geoSearch = function(conditions, options, callback) {
  if (typeof options === 'function') {
    callback = options;
    options = {};
  }
  if (callback) {
    callback = this.$wrapCallback(callback);
  }

  var _this = this;
  var Promise = PromiseProvider.get();
  return new Promise.ES6(function(resolve, reject) {
    var error;
    if (conditions === undefined || !utils.isObject(conditions)) {
      error = new Error('Must pass conditions to geoSearch');
    } else if (!options.near) {
      error = new Error('Must specify the near option in geoSearch');
    } else if (!Array.isArray(options.near)) {
      error = new Error('near option must be an array [x, y]');
    }

    if (error) {
      callback && callback(error);
      reject(error);
      return;
    }

    // send the conditions in the options object
    options.search = conditions;

    _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) {
        callback && callback(err);
        reject(err);
        return;
      }

      var count = res.results.length;
      if (options.lean || count === 0) {
        callback && callback(null, res.results, res.stats);
        resolve(res.results, res.stats);
        return;
      }

      var errSeen = false;

      function init(err) {
        if (err && !errSeen) {
          callback && callback(err);
          reject(err);
          return;
        }

        if (!--count && !errSeen) {
          callback && callback(null, res.results, res.stats);
          resolve(res.results, res.stats);
        }
      }

      for (var i = 0; i < res.results.length; i++) {
        var temp = res.results[i];
        res.results[i] = new _this();
        res.results[i].init(temp, {}, init);
      }
    });
  });
};
参数:
  • conditions <Object> an object that specifies the match condition (required)

  • options <Object> for the geoSearch, some (near, maxDistance) are required

  • [callback] <Function> optional callback

返回值:
参见:

This function does not trigger any middleware

示例:
var options = { near: [10, 10], maxDistance: 5 };
Locations.geoSearch({ type : "house" }, options, function(err, res) {
  console.log(res);
});
选项:
  • 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

24.26. Model.hydrate(obj)

Shortcut for creating a new Document from existing raw data, pre-saved in the DB. The document returned has no paths marked as modified initially.

源码
Model.hydrate = function(obj) {
  var model = require('./queryhelpers').createModel(this, obj);
  model.init(obj);
  return model;
};
参数:
返回值:
示例:
// hydrate previous data into a Mongoose document
var mongooseCandy = Candy.hydrate({ _id: '54108337212ffb6d459f854c', type: 'jelly bean' });

24.27. Model.init([callback])

Performs any async initialization of this model against MongoDB. Currently, this function is only responsible for building indexes, unless autoIndex is turned off.

源码
Model.init = function init(callback) {
  this.schema.emit('init', this);

  if (this.$init) {
    return this.$init;
  }

  var _this = this;
  var Promise = PromiseProvider.get();
  this.$init = new Promise.ES6(function(resolve, reject) {
    if ((_this.schema.options.autoIndex) ||
        (_this.schema.options.autoIndex == null && _this.db.config.autoIndex)) {
      _this.ensureIndexes({ _automatic: true, __noPromise: true }, function(error) {
        if (error) {
          callback && callback(error);
          return reject(error);
        }
        callback && callback(null, _this);
        resolve(_this);
      });
    } else {
      resolve(_this);
    }
  });

  return this.$init;
};
参数:

This function is called automatically, so you don't need to call it. This function is also idempotent, so you may call it to get back a promise that will resolve when your indexes are finished building as an alternative to MyModel.on('index')

示例:
var eventSchema = new Schema({ thing: { type: 'string', unique: true }})
// This calls `Event.init()` implicitly, so you don't need to call
// `Event.init()` on your own.
var Event = mongoose.model('Event', eventSchema);

Event.init().then(function(Event) {
  // You can also use `Event.on('index')` if you prefer event emitters
  // over promises.
  console.log('Indexes are done building!');
});

24.28. Model.insertMany(doc(s), [options], [options.ordered, [options.rawResult, [callback])

Shortcut for validating an array of documents and inserting them into MongoDB if they're all valid. This function is faster than .create() because it only sends one operation to the server, rather than one for each document.

源码
Model.insertMany = function(arr, options, callback) {
  var _this = this;
  if (typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (callback) {
    callback = this.$wrapCallback(callback);
  }
  callback = callback || utils.noop;
  options = options || {};
  var limit = get(options, 'limit', 1000);
  var rawResult = get(options, 'rawResult', false);
  var ordered = get(options, 'ordered', true);

  if (!Array.isArray(arr)) {
    arr = [arr];
  }

  var toExecute = [];
  var validationErrors = [];
  arr.forEach(function(doc) {
    toExecute.push(function(callback) {
      doc = new _this(doc);
      doc.validate({ __noPromise: true }, function(error) {
        if (error) {
          // Option `ordered` signals that insert should be continued after reaching
          // a failing insert. Therefore we delegate "null", meaning the validation
          // failed. It's up to the next function to filter out all failed models
          if (ordered === false) {
            validationErrors.push(error);
            return callback(null, null);
          }
          return callback(error);
        }
        callback(null, doc);
      });
    });
  });

  parallelLimit(toExecute, limit, function(error, docs) {
    if (error) {
      callback && callback(error);
      return;
    }
    // We filter all failed pre-validations by removing nulls
    var docAttributes = docs.filter(function(doc) {
      return doc != null;
    });
    // Quickly escape while there aren't any valid docAttributes
    if (docAttributes.length < 1) {
      callback(null, []);
      return;
    }
    var docObjects = docAttributes.map(function(doc) {
      if (doc.schema.options.versionKey) {
        doc[doc.schema.options.versionKey] = 0;
      }
      if (doc.initializeTimestamps) {
        return doc.initializeTimestamps().toObject(INSERT_MANY_CONVERT_OPTIONS);
      }
      return doc.toObject(INSERT_MANY_CONVERT_OPTIONS);
    });

    _this.collection.insertMany(docObjects, options, function(error, res) {
      if (error) {
        callback && callback(error);
        return;
      }
      for (var i = 0; i < docAttributes.length; ++i) {
        docAttributes[i].isNew = false;
        docAttributes[i].emit('isNew', false);
        docAttributes[i].constructor.emit('isNew', false);
      }
      if (rawResult) {
        if (ordered === false) {
          // Decorate with mongoose validation errors in case of unordered,
          // because then still do `insertMany()`
          res.mongoose = {
            validationErrors: validationErrors
          };
        }
        return callback(null, res);
      }
      callback(null, docAttributes);
    });
  });
};
参数:

doc(s)

  • [options] <Object> see the mongodb driver options

  • [options.ordered &lt;[Boolean][]&gt; = true] if true, will fail fast on the first error encountered. If false, will insert all the documents it can and report errors later. An insertMany() with ordered = false is called an "unordered" insertMany().

  • [options.rawResult &lt;[Boolean][]&gt; = false] if false, the returned promise resolves to the documents that passed mongoose document validation. If false, will return the raw result from the MongoDB driver with a mongoose property that contains validationErrors if this is an unordered insertMany.

  • [callback] <Function> callback

返回值:

Mongoose always validates each document before sending insertMany to MongoDB. So if one document has a validation error, no documents will be saved, unless you set the ordered option to false.

This function does not trigger save middleware.

该函数触发以下中间件

  • insertMany()
示例:
var arr = [{ name: 'Star Wars' }, { name: 'The Empire Strikes Back' }];
Movies.insertMany(arr, function(error, docs) {});

24.29. Model.mapReduce(o, [callback])

Executes a mapReduce command.

源码
Model.mapReduce = function mapReduce(o, callback) {
  var _this = this;
  if (callback) {
    callback = this.$wrapCallback(callback);
  }
  var resolveToObject = o.resolveToObject;
  var Promise = PromiseProvider.get();
  return new Promise.ES6(function(resolve, reject) {
    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 (o.verbose !== false) o.verbose = true;

    o.map = String(o.map);
    o.reduce = String(o.reduce);

    if (o.query) {
      var q = new _this.Query(o.query);
      q.cast(_this);
      o.query = q._conditions;
      q = undefined;
    }

    _this.collection.mapReduce(null, null, o, function(err, ret, stats) {
      if (err) {
        callback && callback(err);
        reject(err);
        return;
      }

      if (ret.findOne && ret.mapReduce) {
        // returned a collection, convert to Model
        var model = Model.compile(
            '_mapreduce_' + ret.collectionName
            , Model.mapReduce.schema
            , ret.collectionName
            , _this.db
            , _this.base);

        model._mapreduce = true;

        callback && callback(null, model, stats);
        return resolveToObject ? resolve({
          model: model,
          stats: stats
        }) : resolve(model, stats);
      }

      callback && callback(null, ret, stats);
      if (resolveToObject) {
        return resolve({ model: ret, stats: stats });
      }
      resolve(ret, stats);
    });
  });
};
参数:
  • o <Object> an object specifying map-reduce options

  • [callback] <Function> optional callback

返回值:
参见:

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 for more detail about options.

This function does not trigger any middleware.

示例:
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)
})
其他选项:
  • 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 > 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 选项:
    • {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).

示例:
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);
  });
})

// `mapReduce()` returns a promise. However, ES6 promises can only
// resolve to exactly one value,
o.resolveToObject = true;
var promise = User.mapReduce(o);
promise.then(function (res) {
  var model = res.model;
  var stats = res.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()

24.30. Model.populate(docs, options, [callback(err,doc)])

Populates document references.

源码
Model.populate = function(docs, paths, callback) {
  var _this = this;
  if (callback) {
    callback = this.$wrapCallback(callback);
  }

  // normalized paths
  var noPromise = paths && !!paths.__noPromise;
  paths = utils.populate(paths);

  // data that should persist across subPopulate calls
  var cache = {};

  if (noPromise) {
    _populate(this, docs, paths, cache, callback);
  } else {
    var Promise = PromiseProvider.get();
    return new Promise.ES6(function(resolve, reject) {
      _populate(_this, docs, paths, cache, function(error, docs) {
        if (error) {
          callback && callback(error);
          reject(error);
        } else {
          callback && callback(null, docs);
          resolve(docs);
        }
      });
    });
  }
};
参数:
  • docs Either a single document or array of documents to populate.

  • options <Object> A hash of key/val (path, options) used for population.

  • [callback(err,doc)] <Function> Optional callback, executed upon completion. Receives err and the doc(s).

返回值:

可用选项:

  • 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
示例:
// 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' }
// and this schema:
// new Schema({
//   name: String,
//   weapon: { type: ObjectId, ref: 'Weapon' }
// });

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
// it is in the schema's ref

24.31. Model.remove(conditions, [callback])

从集合中删除所有匹配 conditions 的文档。 要删除与条件匹配的第一个文档,请设置 single 选项为 true

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

  // get the mongodb collection object
  var mq = new this.Query({}, {}, this, this.collection);

  if (callback) {
    callback = this.$wrapCallback(callback);
  }

  return mq.remove(conditions, callback);
};
参数:
返回值:
示例:
Character.remove({ name: 'Eddard Stark' }, function (err) {});
注意:

该方法直接向 MongoDB 发送一个 remove 命令,不涉及任何 Mongoose 文档。因为没有涉及到 Mongoose 的文档,所以没有执行任何中间件(钩子)。

24.32. Model.replaceOne(conditions, doc, [options], [callback])

Same as update(), except MongoDB replace the existing document with the given document (no atomic operators like $set).

源码
Model.replaceOne = function replaceOne(conditions, doc, options, callback) {
  return _update(this, 'replaceOne', conditions, doc, options, callback);
};
参数:
返回值:

该函数触发以下中间件

  • replaceOne()

24.33. Model.translateAliases(raw)

Translate any aliases fields/conditions so the final query or document object is pure

源码
Model.translateAliases = function translateAliases(fields) {
  var aliases = this.schema.aliases;

  if (typeof fields === 'object') {
    // Fields is an object (query conditions or document fields)
    for (var key in fields) {
      if (aliases[key]) {
        fields[aliases[key]] = fields[key];
        delete fields[key];
      }
    }

    return fields;
  } else {
    // Don't know typeof fields
    return fields;
  }
};
参数:
  • raw <Object> fields/conditions that may contain aliased keys
返回值:
  • <Object> the translated 'pure' fields/conditions
示例:
Character
  .find(Character.translateAliases({
    '名': 'Eddard Stark' // Alias for 'name'
  }))
  .exec(function(err, characters) {})
注意:

Only translate arguments of object type anything else is returned raw

24.34. Model.update(conditions, doc, [options], [callback])

在数据库中更新一个文档而不返回它。

源码
Model.update = function update(conditions, doc, options, callback) {
  return _update(this, 'update', conditions, doc, options, callback);
};
参数:
返回值:
* &lt;[Query][]&gt;
参见:
* [`strict`](/Library/mongoose/docs/guide.md#strict)

* [`response`](http://docs.mongodb.org/v2.6/reference/command/update/#output)

该函数触发以下中间件

* update()
示例:
MyModel.update({ age: { $gt: 18 } }, { oldEnough: true }, fn);
MyModel.update({ name: 'Tobi' }, { ferret: true }, { multi: true }, function (err, raw) {
  if (err) return handleError(err);
  console.log('The raw response from Mongo was ', raw);
});
可用选项:
  • safe (boolean) safe 模式 (默认为 schema 设置的值 (true))
  • upsert (boolean) 如果不匹配,是否创建文档 (false)
  • multi (boolean) 是否需要更新多个文档 (false)
  • runValidators: 如果 true,在此命令上运行更新验证器。更新验证器根据模型的模式的定义验证更新操作。
  • setDefaultsOnInsert: 如果此选项和 upsert 都为 true ,如果创建了一个新文档,那么 Mongoose 将应用模型模式中指定的默认值。这个选项只能工作在 MongoDB >= 2.4,因为因为它依赖于 MongoDB 的 $setOnInsert 操作符。.
  • strict (boolean) 为当前更新覆盖 strict 选项。
  • overwrite (boolean) 禁用 update-only 模式,允许您覆盖文档 (false)

在发送到数据库之前,所有的更新值都被转换为适当的模式类型。

回调函数接受 (err, rawResponse)

  • err 是任何发生的错误
  • rawResponse 在来自 Mongo 完整的响应
注意:

所有非原子操作名称的顶级键都被视为集合操作:

示例:
var query = { name: 'borne' };
Model.update(query, { name: 'jason bourne' }, options, callback)

// 如果 overwrite 选项为 false,作为下面的被发送
Model.update(query, { $set: { name: 'jason bourne' }}, options, callback)
//  如果 overwrite 为 true,不用 $set 包装器发送。

这有助于防止意外地在您的集合中使用 { name: 'jason bourne' } 覆盖所有的文档 。

注意:

注意不要使用现有的模型实例来更新 update 子句(这不会起作用,并且会导致像无限循环这样的怪异行为)。此外,确保更新条款没有一个 _id 属性,这导致 Mongo 返回 "Mod on _id not allowed" 的错误。

注意:

要在不等待 MongoDB 响应的情况下更新文档,请不要通过回调,然后在返回的查询上调用 exec:

Comment.update({ _id: id }, { $set: { text: 'changed' }}).exec();
注意:

尽管在使用更新时,值会被转换到到适当的类型,但以下是不适用的:

  • defaults
  • setters
  • validators
  • middleware

如果您需要这些特性,请使用传统的方法来检索文档。

Model.findOne({ name: 'borne' }, function (err, doc) {
  if (err) ..
  doc.name = 'jason bourne';
  doc.save(callback);
})

24.35. Model.updateMany(conditions, doc, [options], [callback])

Same as update(), except MongoDB will update all documents that match criteria (as opposed to just the first one) regardless of the value of the multi option.

源码
Model.updateMany = function updateMany(conditions, doc, options, callback) {
  return _update(this, 'updateMany', conditions, doc, options, callback);
};
参数:
返回值:
注意:

updateMany will not fire update middleware. Use pre('updateMany') and post('updateMany') instead.

该函数触发以下中间件

  • updateMany()

24.36. Model.updateOne(conditions, doc, [options], [callback])

Same as update(), except MongoDB will update only the first document that matches criteria regardless of the value of the multi option.

源码
Model.updateOne = function updateOne(conditions, doc, options, callback) {
  return _update(this, 'updateOne', conditions, doc, options, callback);
};
参数:
返回值:

该函数触发以下中间件

  • updateOne()

24.37. Model.where(path, [val])

Creates a Query, applies the passed conditions, and returns the Query.

源码
Model.where = function where(path, val) {
  void val; // eslint
  // get the mongodb collection object
  var mq = new this.Query({}, {}, this, this.collection).find({});
  return mq.where.apply(mq, arguments);
};
参数:
返回值:

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

24.38. Model#$where

Additional properties to attach to the query when calling save() and isNew is false.

源码
Model.prototype.$where;

24.39. Model#base

Base Mongoose instance the model uses.

源码
Model.base;

24.40. Model#baseModelName

If this is a discriminator model, baseModelName is the name of the base model.

源码
Model.prototype.baseModelName;

Model.prototype.$__handleSave = function(options, callback) {
  var _this = this;
  var i;
  var keys;
  var len;
  if (!options.safe && this.schema.options.safe) {
    options.safe = this.schema.options.safe;
  }
  if (typeof options.safe === 'boolean') {
    options.safe = null;
  }
  var safe = options.safe ? utils.clone(options.safe, { retainKeyOrder: true }) : options.safe;

  if (this.isNew) {
    // send entire doc
    var toObjectOptions = {};

    toObjectOptions.retainKeyOrder = this.schema.options.retainKeyOrder;
    toObjectOptions.depopulate = 1;
    toObjectOptions._skipDepopulateTopLevel = true;
    toObjectOptions.transform = false;
    toObjectOptions.flattenDecimals = false;

    var obj = this.toObject(toObjectOptions);

    if ((obj || {})._id === void 0) {
      // 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.
      setTimeout(function() {
        callback(new Error('document must have an _id before saving'));
      }, 0);
      return;
    }

    this.$__version(true, obj);
    this.collection.insert(obj, safe, function(err, ret) {
      if (err) {
        _this.isNew = true;
        _this.emit('isNew', true);
        _this.constructor.emit('isNew', true);

        callback(err);
        return;
      }

      callback(null, ret);
    });
    this.$__reset();
    this.isNew = false;
    this.emit('isNew', false);
    this.constructor.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) {
        callback(delta);
        return;
      }

      var where = this.$__where(delta[0]);
      if (where instanceof Error) {
        callback(where);
        return;
      }

      if (this.$where) {
        keys = Object.keys(this.$where);
        len = keys.length;
        for (i = 0; i < len; ++i) {
          where[keys[i]] = this.$where[keys[i]];
        }
      }

      this.collection.update(where, delta[1], safe, function(err, ret) {
        if (err) {
          callback(err);
          return;
        }
        ret.$where = where;
        callback(null, ret);
      });
    } else {
      this.$__reset();
      callback();
      return;
    }

    this.emit('isNew', false);
    this.constructor.emit('isNew', false);
  }
};

24.41. Model#collection

Collection the model uses.

源码
Model.prototype.collection;

24.42. Model#db

Connection the model uses.

源码
Model.prototype.db;

24.43. Model#discriminators

Registered discriminators for this model.

源码
Model.discriminators;

24.44. Model#modelName

The name of the model

源码
Model.prototype.modelName;

24.45. Model#schema

Schema the model uses.

源码
Model.schema;

25. schema/array.js

源码:schema/array.js

25.1. SchemaArray#checkRequired(value)

Check if the given value satisfies a required validator. The given value must be not null nor undefined, and have a positive length.

参数:
返回值:
源码
SchemaArray.prototype.checkRequired = function(value) {
  return !!(value && value.length);
};

25.2. SchemaArray(key, cast, options)

Array SchemaType constructor

参数:
继承:
源码
function SchemaArray(key, cast, options, schemaOptions) {
  var typeKey = 'type';
  if (schemaOptions && schemaOptions.typeKey) {
    typeKey = schemaOptions.typeKey;
  }

  if (cast) {
    var castOptions = {};

    if (utils.getFunctionName(cast.constructor) === 'Object') {
      if (cast[typeKey]) {
        // support { type: Woot }
        castOptions = utils.clone(cast); // do not alter user arguments
        delete castOptions[typeKey];
        cast = cast[typeKey];
      } else {
        cast = Mixed;
      }
    }

    // support { type: 'String' }
    var name = typeof cast === 'string'
        ? cast
        : utils.getFunctionName(cast);

    var caster = name in Types
        ? Types[name]
        : cast;

    this.casterConstructor = caster;
    if (typeof caster === 'function' && !caster.$isArraySubdocument) {
      this.caster = new caster(null, castOptions);
    } else {
      this.caster = caster;
    }

    if (!(this.caster instanceof EmbeddedDoc)) {
      this.caster.path = key;
    }
  }

  this.$isMongooseArray = true;

  SchemaType.call(this, key, options, 'Array');

  var defaultArr;
  var fn;

  if (this.defaultValue != null) {
    defaultArr = this.defaultValue;
    fn = typeof defaultArr === 'function';
  }

  if (!('defaultValue' in this) || this.defaultValue !== void 0) {
    this.default(function() {
      var arr = [];
      if (fn) {
        arr = defaultArr();
      } else if (defaultArr != null) {
        arr = arr.concat(defaultArr);
      }
      // Leave it up to `cast()` to convert the array
      return arr;
    });
  }
}

25.3. SchemaArray.schemaName

This schema type's name, to defend against minifiers that mangle function names.

源码
SchemaArray.schemaName = 'Array';

26. schema/boolean.js

源码:schema/boolean.js

26.1. SchemaBoolean#checkRequired(value)

Check if the given value satisfies a required validator. For a boolean to satisfy a required validator, it must be strictly equal to true or to false.

参数:
返回值:
源码
SchemaBoolean.prototype.checkRequired = function(value) {
  return value === true || value === false;
};

26.2. SchemaBoolean(path, options)

Boolean SchemaType constructor.

参数:
继承:
源码
function SchemaBoolean(path, options) {
  SchemaType.call(this, path, options, 'Boolean');
}

26.3. SchemaBoolean.schemaName

This schema type's name, to defend against minifiers that mangle function names.

源码
SchemaBoolean.schemaName = 'Boolean';

27. schema/mixed.js

源码:schema/mixed.js

27.1. Mixed(path, options)

Mixed SchemaType 构造函数。

参数:
继承:
源码
function Mixed(path, options) {
  if (options && options.default) {
    var def = options.default;
    if (Array.isArray(def) && def.length === 0) {
      // make sure empty array defaults are handled
      options.default = Array;
    } else if (!options.shared && utils.isObject(def) && Object.keys(def).length === 0) {
      // prevent odd "shared" objects between documents
      options.default = function() {
        return {};
      };
    }
  }

  SchemaType.call(this, path, options, 'Mixed');
}

27.2. Mixed.schemaName

这个模式类型的名称,用来防御那些损坏函数原命名的代码压缩器。

源码
Mixed.schemaName = 'Mixed';

28. schema/embedded.js

源码:schema/embedded.js

28.1. Embedded#discriminator(name, schema)

Adds a discriminator to this property

参数:
  • name <String>

  • schema fields to add to the schema for instances of this sub-class

源码
Embedded.prototype.discriminator = function(name, schema) {
  discriminator(this.caster, name, schema);

  this.caster.discriminators[name] = _createConstructor(schema);

  return this.caster.discriminators[name];
};

28.2. Embedded(schema, key, options)

Sub-schema schematype constructor

参数:
继承:
源码
function Embedded(schema, path, options) {
  this.caster = _createConstructor(schema);
  this.caster.prototype.$basePath = path;
  this.schema = schema;
  this.$isSingleNested = true;
  SchemaType.call(this, path, options, 'Embedded');
}

29. schema/buffer.js

源码:schema/buffer.js

29.1. SchemaBuffer#checkRequired(value, doc)

Check if the given value satisfies a required validator. To satisfy a required validator, a buffer must not be null or undefined and have non-zero length.

参数:
返回值:

<Boolean>

源码
SchemaBuffer.prototype.checkRequired = function(value, doc) {
  if (SchemaType._isRef(this, value, doc, true)) {
    return !!value;
  }
  return !!(value && value.length);
};

29.2. SchemaBuffer(key, options)

Buffer SchemaType constructor

参数:
继承:
源码
function SchemaBuffer(key, options) {
  SchemaType.call(this, key, options, 'Buffer');
}

29.3. SchemaBuffer#subtype(subtype)

Sets the default subtype for this buffer. You can find a list of allowed subtypes here.

参数:
  • subtype <Number> the default subtype
返回值:
  • this
示例:
var s = new Schema({ uuid: { type: Buffer, subtype: 4 }});
var M = db.model('M', s);
var m = new M({ uuid: 'test string' });
m.uuid._subtype; // 4
源码
SchemaBuffer.prototype.subtype = function(subtype) {
  this.options.subtype = subtype;
  return this;
};

29.4. SchemaBuffer.schemaName

This schema type's name, to defend against minifiers that mangle function names.

源码
SchemaBuffer.schemaName = 'Buffer';

30. schema/objectid.js

源码:schema/objectid.js

30.1. ObjectId#auto(turnOn)

Adds an auto-generated ObjectId default if turnOn is true.

参数:
  • turnOn <Boolean> auto generated ObjectId defaults
返回值:
  • this
源码
ObjectId.prototype.auto = function(turnOn) {
  if (turnOn) {
    this.default(defaultId);
    this.set(resetId);
  }

  return this;
};

30.2. ObjectId#checkRequired(value, doc)

Check if the given value satisfies a required validator.

参数:
返回值:
源码
ObjectId.prototype.checkRequired = function checkRequired(value, doc) {
  if (SchemaType._isRef(this, value, doc, true)) {
    return !!value;
  }
  return value instanceof oid;
};

30.3. ObjectId(key, options)

ObjectId SchemaType constructor.

参数:
继承:
  • SchemaType
源码
function ObjectId(key, options) {
  var isKeyHexStr = typeof key === 'string' && key.length === 24 && /^a-f0-9$/i.test(key);
  var suppressWarning = options && options.suppressWarning;
  if ((isKeyHexStr || typeof key === 'undefined') && !suppressWarning) {
    console.warn('mongoose: To create a new ObjectId please try ' +
      '`Mongoose.Types.ObjectId` instead of using ' +
      '`Mongoose.Schema.ObjectId`. Set the `suppressWarning` option if ' +
      'you\'re trying to create a hex char path in your schema.');
    console.trace();
  }
  SchemaType.call(this, key, options, 'ObjectID');
}

30.4. ObjectId.schemaName

This schema type's name, to defend against minifiers that mangle function names.

源码
ObjectId.schemaName = 'ObjectId';

31. schema/string.js

源码:schema/string.js

31.1. SchemaString#checkRequired(value, doc)

Check if the given value satisfies the required validator. The value is considered valid if it is a string (that is, not null or undefined) and has positive length. The required validator will fail for empty strings.

参数:
返回值:
源码
SchemaString.prototype.checkRequired = function checkRequired(value, doc) {
  if (SchemaType._isRef(this, value, doc, true)) {
    return !!value;
  }
  return (value instanceof String || typeof value === 'string') && value.length;
};

31.2. SchemaString#enum([args...])

Adds an enum validator

参数:
  • [args...] enumeration values
返回值:
  • this
参见:
示例:
var states = ['opening', 'open', 'closing', 'closed']
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 enum = {
  values: ['opening', 'open', 'closing', 'closed'],
  message: 'enum validator failed for path `{PATH}` with value `{VALUE}`'
}
var s = new Schema({ state: { type: String, enum: enum }})
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
})
源码
SchemaString.prototype.enum = function() {
  if (this.enumValidator) {
    this.validators = this.validators.filter(function(v) {
      return v.validator !== this.enumValidator;
    }, this);
    this.enumValidator = false;
  }

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

  var values;
  var errorMessage;

  if (utils.isObject(arguments[0])) {
    values = arguments[0].values;
    errorMessage = arguments[0].message;
  } else {
    values = arguments;
    errorMessage = MongooseError.messages.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({
    validator: this.enumValidator,
    message: errorMessage,
    type: 'enum',
    enumValues: vals
  });

  return this;
};

31.3. SchemaString#lowercase()

Adds a lowercase setter.

返回值:
  • this
示例:
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
注意:

Setters do not run on queries by default. Use the runSettersOnQuery option:

 // Must use `runSettersOnQuery` as shown below, otherwise `email` will
 // **not** be lowercased.
 M.updateOne({}, { $set: { email: 'SomeEmail@example.COM' } }, { runSettersOnQuery: true });
源码
SchemaString.prototype.lowercase = function(shouldApply) {
  if (arguments.length > 0 && !shouldApply) {
    return this;
  }
  return this.set(function(v, self) {
    if (typeof v !== 'string') {
      v = self.cast(v);
    }
    if (v) {
      return v.toLowerCase();
    }
    return v;
  });
};

31.4. SchemaString#match(regExp, [message])

Sets a regexp validator.

参数:
  • regExp regular expression to test against

  • [message] <String> optional custom error message

返回值:
  • this
参见:

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

示例:
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 }})
源码
SchemaString.prototype.match = function match(regExp, message) {
  // yes, we allow multiple match validators

  var msg = message || MongooseError.messages.String.match;

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

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

  this.validators.push({
    validator: matchValidator,
    message: msg,
    type: 'regexp',
    regexp: regExp
  });
  return this;
};

31.5. SchemaString#maxlength(value, [message])

Sets a maximum length validator.

参数:
* `value` &lt;[Number][]&gt; maximum string length

* `[message]` &lt;[String][]&gt; optional custom error message
返回值:
* <SchemaType> this
参见:
* [定制的 Error Messages](#MongooseError_messages)()
示例:
var schema = new Schema({ postalCode: { type: String, maxlength: 9 }})
var Address = db.model('Address', schema)
var address = new Address({ postalCode: '9512512345' })
address.save(function (err) {
  console.error(err) // validator error
  address.postalCode = '95125';
  address.save() // success
})

// custom error messages
// We can also use the special {MAXLENGTH} token which will be replaced with the maximum allowed length
var maxlength = [9, 'The value of path `{PATH}` (`{VALUE}`) exceeds the maximum allowed length ({MAXLENGTH}).'];
var schema = new Schema({ postalCode: { type: String, maxlength: maxlength }})
var Address = mongoose.model('Address', schema);
var address = new Address({ postalCode: '9512512345' });
address.validate(function (err) {
  console.log(String(err)) // ValidationError: The value of path `postalCode` (`9512512345`) exceeds the maximum allowed length (9).
})
源码
SchemaString.prototype.maxlength = function(value, message) {
  if (this.maxlengthValidator) {
    this.validators = this.validators.filter(function(v) {
      return v.validator !== this.maxlengthValidator;
    }, this);
  }

  if (value !== null && value !== undefined) {
    var msg = message || MongooseError.messages.String.maxlength;
    msg = msg.replace(/{MAXLENGTH}/, value);
    this.validators.push({
      validator: this.maxlengthValidator = function(v) {
        return v === null || v.length <= value;
      },
      message: msg,
      type: 'maxlength',
      maxlength: value
    });
  }

  return this;
};

31.6. SchemaString#minlength(value, [message])

Sets a minimum length validator.

参数:
  • value <Number> minimum string length

  • [message] <String> optional custom error message

返回值:
  • this
参见:
  • [Customized Error Messages
示例:
var schema = new Schema({ postalCode: { type: String, minlength: 5 }})
var Address = db.model('Address', schema)
var address = new Address({ postalCode: '9512' })
address.save(function (err) {
  console.error(err) // validator error
  address.postalCode = '95125';
  address.save() // success
})

// custom error messages
// We can also use the special {MINLENGTH} token which will be replaced with the minimum allowed length
var minlength = [5, 'The value of path `{PATH}` (`{VALUE}`) is shorter than the minimum allowed length ({MINLENGTH}).'];
var schema = new Schema({ postalCode: { type: String, minlength: minlength }})
var Address = mongoose.model('Address', schema);
var address = new Address({ postalCode: '9512' });
address.validate(function (err) {
  console.log(String(err)) // ValidationError: The value of path `postalCode` (`9512`) is shorter than the minimum length (5).
})
源码
SchemaString.prototype.minlength = function(value, message) {
  if (this.minlengthValidator) {
    this.validators = this.validators.filter(function(v) {
      return v.validator !== this.minlengthValidator;
    }, this);
  }

  if (value !== null && value !== undefined) {
    var msg = message || MongooseError.messages.String.minlength;
    msg = msg.replace(/{MINLENGTH}/, value);
    this.validators.push({
      validator: this.minlengthValidator = function(v) {
        return v === null || v.length >= value;
      },
      message: msg,
      type: 'minlength',
      minlength: value
    });
  }

  return this;
};

31.7. SchemaString(key, options)

String SchemaType constructor.

参数:
继承:
源码
function SchemaString(key, options) {
  this.enumValues = [];
  this.regExp = null;
  SchemaType.call(this, key, options, 'String');
}

31.8. SchemaString#trim()

Adds a trim setter.

返回值:
  • this

The string value will be trimmed when set.

示例:
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
注意:

Setters do not run on queries by default. Use the runSettersOnQuery option:

 // Must use `runSettersOnQuery` as shown below, otherwise `email` will
 // **not** be lowercased.
 M.updateOne({}, { $set: { email: 'SomeEmail@example.COM' } }, { runSettersOnQuery: true });
源码
SchemaString.prototype.trim = function(shouldTrim) {
  if (arguments.length > 0 && !shouldTrim) {
    return this;
  }
  return this.set(function(v, self) {
    if (typeof v !== 'string') {
      v = self.cast(v);
    }
    if (v) {
      return v.trim();
    }
    return v;
  });
};

31.9. SchemaString#uppercase()

Adds an uppercase setter.

返回值:
  • this
示例:
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
注意:

Setters do not run on queries by default. Use the runSettersOnQuery option:

 // Must use `runSettersOnQuery` as shown below, otherwise `email` will
 // **not** be lowercased.
 M.updateOne({}, { $set: { email: 'SomeEmail@example.COM' } }, { runSettersOnQuery: true });
源码
SchemaString.prototype.uppercase = function(shouldApply) {
  if (arguments.length > 0 && !shouldApply) {
    return this;
  }
  return this.set(function(v, self) {
    if (typeof v !== 'string') {
      v = self.cast(v);
    }
    if (v) {
      return v.toUpperCase();
    }
    return v;
  });
};

31.10. SchemaString.schemaName

This schema type's name, to defend against minifiers that mangle function names.

源码
SchemaString.schemaName = 'String';

32. schema/decimal128.js

源码:schema/decimal128.js

32.1. Decimal128#checkRequired(value, doc)

Check if the given value satisfies a required validator.

参数:
返回值:
源码
Decimal128.prototype.checkRequired = function checkRequired(value, doc) {
  if (SchemaType._isRef(this, value, doc, true)) {
    return !!value;
  }
  return value instanceof Decimal128Type;
};

32.2. Decimal128(key, options)

Decimal128 SchemaType constructor.

参数:
继承:
源码
function Decimal128(key, options) {
  SchemaType.call(this, key, options, 'Decimal128');
}

32.3. Decimal128.schemaName

This schema type's name, to defend against minifiers that mangle function names.

源码
Decimal128.schemaName = 'Decimal128';

33. schema/documentarray.js

33.1. DocumentArray(key, schema, options)

SubdocsArray SchemaType constructor

参数:
继承:
源码
function DocumentArray(key, schema, options) {
  var EmbeddedDocument = _createConstructor(schema, options);
  EmbeddedDocument.prototype.$basePath = key;

  ArrayType.call(this, key, EmbeddedDocument, options);

  this.schema = schema;
  this.$isMongooseDocumentArray = true;
  var fn = this.defaultValue;

  if (!('defaultValue' in this) || fn !== void 0) {
    this.default(function() {
      var arr = fn.call(this);
      if (!Array.isArray(arr)) {
        arr = [arr];
      }
      // Leave it up to `cast()` to convert this to a documentarray
      return arr;
    });
  }
}

33.2. DocumentArray.schemaName

This schema type's name, to defend against minifiers that mangle function names.

源码
DocumentArray.schemaName = 'DocumentArray';

34. schema/date.js

源码:schema/date.js

34.1. SchemaDate#checkRequired(value, doc)

检查给定值是否满足需要的(required)验证器。为了满足必需的验证器,给定的值必须是一个 Date 的实例。

参数:
返回值:
源码
SchemaDate.prototype.checkRequired = function(value) {
  return value instanceof Date;
};

34.2. SchemaDate#expires(when)

Date 类型声明一个 TTL 索引(四舍五入到最近的秒)。

参数:
  • when
返回值:
  • this

这将设置 MongoDB 的 expireAfterSeconds 索引选项。「译者注」:表示到期时间 该索引类型仅与日期 Date 类型兼容。

示例:
// 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:
示例:
// 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');
源码
SchemaDate.prototype.expires = function(when) {
  if (!this._index || this._index.constructor.name !== 'Object') {
    this._index = {};
  }

  this._index.expires = when;
  utils.expires(this._index);
  return this;
};

34.3. SchemaDate#max(maximum, [message])

设置一个最大日期验证器。

参数:
  • maximum date

  • [message] <String> 可选,自定义的错误信息

返回值:
  • this
参见:
示例:
var s = new Schema({ d: { type: Date, max: Date('2014-01-01') }})
var M = db.model('M', s)
var m = new M({ d: Date('2014-12-08') })
m.save(function (err) {
  console.error(err) // validator error
  m.d = Date('2013-12-31');
  m.save() // success
})

// custom error messages
// We can also use the special {MAX} token which will be replaced with the invalid value
var max = [Date('2014-01-01'), 'The value of path `{PATH}` ({VALUE}) exceeds the limit ({MAX}).'];
var schema = new Schema({ d: { type: Date, max: max }})
var M = mongoose.model('M', schema);
var s= new M({ d: Date('2014-12-08') });
s.validate(function (err) {
  console.log(String(err)) // ValidationError: The value of path `d` (2014-12-08) exceeds the limit (2014-01-01).
})
源码
SchemaDate.prototype.max = function(value, message) {
  if (this.maxValidator) {
    this.validators = this.validators.filter(function(v) {
      return v.validator !== this.maxValidator;
    }, this);
  }

  if (value) {
    var msg = message || MongooseError.messages.Date.max;
    msg = msg.replace(/{MAX}/, (value === Date.now ? 'Date.now()' : this.cast(value).toString()));
    var _this = this;
    this.validators.push({
      validator: this.maxValidator = function(val) {
        var max = (value === Date.now ? value() : _this.cast(value));
        return val === null || val.valueOf() <= max.valueOf();
      },
      message: msg,
      type: 'max',
      max: value
    });
  }

  return this;
};

34.4. SchemaDate#min(value, [message])

设置一个最小日期验证器。

参数:
  • value 最小日期

  • [message] <String> 可选,自定义错误消息

返回值:
  • this
参见:
示例:
var s = new Schema({ d: { type: Date, min: Date('1970-01-01') }})
var M = db.model('M', s)
var m = new M({ d: Date('1969-12-31') })
m.save(function (err) {
  console.error(err) // validator error
  m.d = Date('2014-12-08');
  m.save() // success
})

// custom error messages
// We can also use the special {MIN} token which will be replaced with the invalid value
var min = [Date('1970-01-01'), 'The value of path `{PATH}` ({VALUE}) is beneath the limit ({MIN}).'];
var schema = new Schema({ d: { type: Date, min: min }})
var M = mongoose.model('M', schema);
var s= new M({ d: Date('1969-12-31') });
s.validate(function (err) {
  console.log(String(err)) // ValidationError: The value of path `d` (1969-12-31) is before the limit (1970-01-01).
})
源码
SchemaDate.prototype.min = function(value, message) {
  if (this.minValidator) {
    this.validators = this.validators.filter(function(v) {
      return v.validator !== this.minValidator;
    }, this);
  }

  if (value) {
    var msg = message || MongooseError.messages.Date.min;
    msg = msg.replace(/{MIN}/, (value === Date.now ? 'Date.now()' : this.cast(value).toString()));
    var _this = this;
    this.validators.push({
      validator: this.minValidator = function(val) {
        var min = (value === Date.now ? value() : _this.cast(value));
        return val === null || val.valueOf() >= min.valueOf();
      },
      message: msg,
      type: 'min',
      min: value
    });
  }

  return this;
};

34.5. SchemaDate(key, options)

Date SchemaType 构造函数。

参数:
继承:
源码
function SchemaDate(key, options) {
  SchemaType.call(this, key, options, 'Date');
}

34.6. SchemaDate.schemaName

这个模式类型的名称,用来防御那些损害函数原名称的压缩器。

源码
SchemaDate.schemaName = 'Date';

35. schema/number.js

源码:schema/number.js

35.1. SchemaNumber#checkRequired(value, doc)

Check if the given value satisfies a required validator.

参数:
返回值:
源码
SchemaNumber.prototype.checkRequired = function checkRequired(value, doc) {
  if (SchemaType._isRef(this, value, doc, true)) {
    return !!value;
  }
  return typeof value === 'number' || value instanceof Number;
};

35.2. SchemaNumber#max(maximum, [message])

Sets a maximum number validator.

参数:
  • maximum <Number> number

  • [message] <String> optional custom error message

返回值:
  • this
参见:
示例:
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).
})
源码
SchemaNumber.prototype.max = function(value, message) {
  if (this.maxValidator) {
    this.validators = this.validators.filter(function(v) {
      return v.validator !== this.maxValidator;
    }, this);
  }

  if (value !== null && value !== undefined) {
    var msg = message || MongooseError.messages.Number.max;
    msg = msg.replace(/{MAX}/, value);
    this.validators.push({
      validator: this.maxValidator = function(v) {
        return v == null || v <= value;
      },
      message: msg,
      type: 'max',
      max: value
    });
  }

  return this;
};

35.3. SchemaNumber#min(value, [message])

Sets a minimum number validator.

参数:
  • value <Number> minimum number

  • [message] <String> optional custom error message

返回值:
  • this
参见:
示例:
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).
})
源码
SchemaNumber.prototype.min = function(value, message) {
  if (this.minValidator) {
    this.validators = this.validators.filter(function(v) {
      return v.validator !== this.minValidator;
    }, this);
  }

  if (value !== null && value !== undefined) {
    var msg = message || MongooseError.messages.Number.min;
    msg = msg.replace(/{MIN}/, value);
    this.validators.push({
      validator: this.minValidator = function(v) {
        return v == null || v >= value;
      },
      message: msg,
      type: 'min',
      min: value
    });
  }

  return this;
};

35.4. SchemaNumber(key, options)

Number SchemaType constructor.

参数:
继承:
源码
function SchemaNumber(key, options) {
  SchemaType.call(this, key, options, 'Number');
}

35.5. SchemaNumber.schemaName

This schema type's name, to defend against minifiers that mangle function names.

源码
SchemaNumber.schemaName = 'Number';

36. cursor/QueryCursor.js

源码:cursor/QueryCursor.js

36.1. QueryCursor#addCursorFlag(flag, value)

Adds a cursor flag. Useful for setting the noCursorTimeout and tailable flags.

参数:
返回值:
  • this

36.2. QueryCursor#close(callback)

Marks this cursor as closed. Will stop streaming and subsequent calls to next() will error.

参数:
返回值:
参见:

36.3. QueryCursor#eachAsync(fn, [options], [options.parallel], [callback])

Execute fn for every document in the cursor. If fn returns a promise, will wait for the promise to resolve before iterating on to the next one. Returns a promise that resolves when done.

参数:
  • fn <Function>

  • [options] <Object>

  • [options.parallel] <Number> the number of promises to execute in parallel. Defaults to 1.

  • [callback] <Function> executed when all docs have been processed

返回值:

36.4. QueryCursor#map(fn)

Registers a transform function which subsequently maps documents retrieved via the streams interface or .next()

参数:
返回值:
示例:
// Map documents returned by `data` events
Thing.
  find({ name: /^hello/ }).
  cursor().
  map(function (doc) {
   doc.foo = "bar";
   return doc;
  })
  on('data', function(doc) { console.log(doc.foo); });

// Or map documents returned by `.next()`
var cursor = Thing.find({ name: /^hello/ }).
  cursor().
  map(function (doc) {
    doc.foo = "bar";
    return doc;
  });
cursor.next(function(error, doc) {
  console.log(doc.foo);
});

36.5. QueryCursor#next(callback)

Get the next document from this cursor. Will return null when there are no documents left.

参数:
返回值:

36.6. QueryCursor(query, options)

A QueryCursor is a concurrency primitive for processing query results one document at a time. A QueryCursor fulfills the Node.js streams3 API, in addition to several other mechanisms for loading documents from MongoDB one at a time.

参数:
  • query <Query>

  • options <Object> query options passed to .find()

继承:
事件:

cursor: Emitted when the cursor is created

error: Emitted when an error occurred

data: Emitted when the stream is flowing and the next doc is ready

end: Emitted when the stream is exhausted

QueryCursors execute the model's pre find hooks, but not the model's post find hooks.

Unless you're an advanced user, do not instantiate this class directly. Use Query#cursor() instead.

源码
function QueryCursor(query, options) {
  Readable.call(this, { objectMode: true });

  this.cursor = null;
  this.query = query;
  this._transforms = options.transform ? [options.transform] : [];
  var _this = this;
  var model = query.model;
  model.hooks.execPre('find', query, function() {
    model.collection.find(query._conditions, options, function(err, cursor) {
      if (_this._error) {
        cursor.close(function() {});
        _this.listeners('error').length > 0 && _this.emit('error', _this._error);
      }
      if (err) {
        return _this.emit('error', err);
      }
      _this.cursor = cursor;
      _this.emit('cursor', cursor);
    });
  });
}

util.inherits(QueryCursor, Readable);

37. cursor/AggregationCursor.js

源码:cursor/AggregationCursor.js

37.1. AggregationCursor#addCursorFlag(flag, value)

Adds a cursor flag. Useful for setting the noCursorTimeout and tailable flags.

参数:
返回值:
  • this

37.2. AggregationCursor(agg, options)

An AggregationCursor is a concurrency primitive for processing aggregation results one document at a time. It is analogous to QueryCursor.

参数:
继承:
事件:

cursor: Emitted when the cursor is created

error: Emitted when an error occurred

data: Emitted when the stream is flowing and the next doc is ready

end: Emitted when the stream is exhausted

An AggregationCursor fulfills the Node.js streams3 API, in addition to several other mechanisms for loading documents from MongoDB one at a time.

Creating an AggregationCursor executes the model's pre aggregate hooks, but not the model's post aggregate hooks.

Unless you're an advanced user, do not instantiate this class directly. Use Aggregate#cursor() instead.

源码
function AggregationCursor(agg) {
  Readable.call(this, { objectMode: true });

  this.cursor = null;
  this.agg = agg;
  this._transforms = [];
  var model = agg._model;
  delete agg.options.cursor.useMongooseAggCursor;

  _init(model, this, agg);
}

util.inherits(AggregationCursor, Readable);

37.3. AggregationCursor#close(callback)

Marks this cursor as closed. Will stop streaming and subsequent calls to next() will error.

参数:
返回值:
参见:

37.4. AggregationCursor#eachAsync(fn, [callback])

Execute fn for every document in the cursor. If fn returns a promise, will wait for the promise to resolve before iterating on to the next one. Returns a promise that resolves when done.

参数:
  • fn <Function>

  • [callback] <Function> executed when all docs have been processed

返回值:

37.5. AggregationCursor#map(fn)

Registers a transform function which subsequently maps documents retrieved via the streams interface or .next()

参数:
返回值:
示例:
// Map documents returned by `data` events
Thing.
  find({ name: /^hello/ }).
  cursor().
  map(function (doc) {
   doc.foo = "bar";
   return doc;
  })
  on('data', function(doc) { console.log(doc.foo); });

// Or map documents returned by `.next()`
var cursor = Thing.find({ name: /^hello/ }).
  cursor().
  map(function (doc) {
    doc.foo = "bar";
    return doc;
  });
cursor.next(function(error, doc) {
  console.log(doc.foo);
});

37.6. AggregationCursor#next(callback)

Get the next document from this cursor. Will return null when there are no documents left.

参数:
返回值:

38. schematype.js

源码:schematype.js

38.1. SchemaType#default(val)

Sets a default value for this SchemaType.

参数:
  • val the default value
返回值:
示例:
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.

示例:
// values are cast:
var schema = new Schema({ aNumber: { type: 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 }
源码
SchemaType.prototype.default = function(val) {
  if (arguments.length === 1) {
    if (val === void 0) {
      this.defaultValue = void 0;
      return void 0;
    }
    this.defaultValue = val;
    return this.defaultValue;
  } else if (arguments.length > 1) {
    this.defaultValue = utils.args(arguments);
  }
  return this.defaultValue;
};

38.2. SchemaType#get(fn)

Adds a getter to this schematype.

参数:
返回值:
  • this
示例:
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
})
源码
SchemaType.prototype.get = function(fn) {
  if (typeof fn !== 'function') {
    throw new TypeError('A getter must be a function.');
  }
  this.getters.push(fn);
  return this;
};

38.3. SchemaType#index(options)

Declares the index options for this schematype.

参数:
  • options
返回值:
  • this
示例:
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 });
注意:

Indexes are created in the background by default. Specify background: false to override.

Direction doesn't matter for single key indexes

源码
SchemaType.prototype.index = function(options) {
  this._index = options;
  utils.expires(this._index);
  return this;
};

38.4. SchemaType#required(required, [options.isRequired], [options.ErrorConstructor], [message])

Adds a required validator to this SchemaType. The validator gets added to the front of this SchemaType's validators array using unshift().

参数:
  • required enable/disable the validator, or function that returns required boolean, or options object

  • [options.isRequired] enable/disable the validator, or function that returns required boolean

  • [options.ErrorConstructor] <Function> custom error constructor. The constructor receives 1 parameter, an object containing the validator properties.

  • [message] <String> optional custom error message

返回值:
  • this
参见:
示例:
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 with a function

var s = new Schema({
  userId: ObjectId,
  username: {
    type: String,
    required: function() { return this.userId != null; }
  }
})

// or with a function and a custom message
var s = new Schema({
  userId: ObjectId,
  username: {
    type: String,
    required: [
      function() { return this.userId != null; },
      'username is required if id is specified'
    ]
  }
})

// or through the path API

Schema.path('name').required(true);

// with custom error messaging

Schema.path('name').required(true, 'grrr :( ');

// or make a path conditionally required based on a function
var isOver18 = function() { return this.age &gt;= 18; };
Schema.path('voterRegistrationId').required(isOver18);

The required validator uses the SchemaType's checkRequired function to determine whether a given value satisfies the required validator. By default, a value satisfies the required validator if val != null (that is, if the value is not null nor undefined). However, most built-in mongoose schema types override the default checkRequired function:

源码
SchemaType.prototype.required = function(required, message) {
  var customOptions = {};
  if (typeof required === 'object') {
    customOptions = required;
    message = customOptions.message || message;
    required = required.isRequired;
  }

  if (required === false) {
    this.validators = this.validators.filter(function(v) {
      return v.validator !== this.requiredValidator;
    }, this);

    this.isRequired = false;
    return this;
  }

  var _this = 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(_this.path) && !this.isModified(_this.path)) {
      return true;
    }

    return ((typeof required === 'function') && !required.apply(this)) ||
        _this.checkRequired(v, this);
  };
  this.originalRequiredValue = required;

  if (typeof required === 'string') {
    message = required;
    required = undefined;
  }

  var msg = message || MongooseError.messages.general.required;
  this.validators.unshift(utils.assign({}, customOptions, {
    validator: this.requiredValidator,
    message: msg,
    type: 'required'
  }));

  return this;
};

38.5. SchemaType(path, [options], [instance])

SchemaType 构造函数

参数:
源码
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 prop in options) {
    if (this[prop] && typeof this[prop] === 'function') {
      // { unique: true, index: true }
      if (prop === 'index' && this._index) {
        continue;
      }

      var val = options[prop];
      // Special case so we don't screw up array defaults, see gh-5780
      if (prop === 'default') {
        this.default(val);
        continue;
      }

      var opts = Array.isArray(val) ? val : [val];

      this[prop].apply(this, opts);
    }
  }

  Object.defineProperty(this, '$$context', {
    enumerable: false,
    configurable: false,
    writable: true,
    value: null
  });
}

38.6. SchemaType#select(val)

Sets default select() behavior for this path.

参数:
返回值:
  • this

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.

示例:
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);
源码
SchemaType.prototype.select = function select(val) {
  this.selected = !!val;
  return this;
};

38.7. SchemaType#set(fn)

Adds a setter to this schematype.

参数:
返回值:
  • this
示例:
function capitalize (val) {
  if (typeof val !== 'string') 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 stored in MongoDB.

注意:

setters by default do not run on queries by default.

// Will not run the toLower() setter by default. User.updateOne({ _id: _id }, { $set: { email: 'AVENUE@Q.COM' } }); Use the runSettersOnQuery option to opt-in to running setters on User.update():

// Turn on runSettersOnQuery to run the setters from your schema. User.updateOne({ _id: _id }, { $set: { email: 'AVENUE@Q.COM' } }, { runSettersOnQuery: true });

注意:

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
源码
SchemaType.prototype.set = function(fn) {
  if (typeof fn !== 'function') {
    throw new TypeError('A setter must be a function.');
  }
  this.setters.push(fn);
  return this;
};

38.8. SchemaType#sparse(bool)

Declares a sparse index.

参数:
返回值:
  • this
示例:
var s = new Schema({ name: { type: String, sparse: true }})
Schema.path('name').index({ sparse: true });
源码
SchemaType.prototype.sparse = function(bool) {
  if (this._index === null || this._index === undefined ||
    typeof this._index === 'boolean') {
    this._index = {};
  } else if (typeof this._index === 'string') {
    this._index = {type: this._index};
  }

  this._index.sparse = bool;
  return this;
};

38.9. SchemaType#text(bool)

Declares a full text index.

参数:
返回值:
  • this
示例:
var s = new Schema({name : {type: String, text : true }})
 Schema.path('name').index({text : true});
源码
SchemaType.prototype.text = function(bool) {
  if (this._index === null || this._index === undefined ||
    typeof this._index === 'boolean') {
    this._index = {};
  } else if (typeof this._index === 'string') {
    this._index = {type: this._index};
  }

  this._index.text = bool;
  return this;
};

38.10. SchemaType#unique(bool)

Declares an unique index.

参数:
返回值:
  • this
示例:
var s = new Schema({ name: { type: String, unique: true }});
Schema.path('name').index({ unique: true });
注意:

violating the constraint returns an E11000 error from MongoDB when saving, not a Mongoose validation error.

源码
SchemaType.prototype.unique = function(bool) {
  if (this._index === false) {
    if (!bool) {
      return;
    }
    throw new Error('Path "' + this.path + '" may not have `index` set to ' +
      'false and `unique` set to true');
  }
  if (this._index == null || this._index === true) {
    this._index = {};
  } else if (typeof this._index === 'string') {
    this._index = {type: this._index};
  }

  this._index.unique = bool;
  return this;
};

38.11. SchemaType#validate(obj, [errorMsg], [type])

为当前文档路径添加验证器

参数:
  • obj 验证器

  • [errorMsg] <String> 可选,错误信息

  • [type] <String> 可选,验证器类型

返回值:
  • this

验证器总是接收需要验证的值作为第一个参数,并且必须返回 Boolean。返回 false 意味着验证失败。

错误消息参数是可选的。如果没有通过,将使用默认的通用错误消息模板

示例:
// 确保每个值等于  "something"
function validator (val) {
  return val == 'something';
}
new Schema({ name: { type: String, validate: validator }});

// 使用自定义的错误信息

var custom = [validator, 'Uh oh, {PATH} does not equal "something".']
new Schema({ name: { type: String, validate: custom }});

// 同时添加多个验证器

var many = [
    { validator: validator, msg: 'uh oh' }
  , { validator: anotherValidator, msg: 'failed' }
]
new Schema({ name: { type: String, validate: many }});

// 或者直接利用 SchemaType 方法:

var schema = new Schema({ name: 'string' });
schema.path('name').validate(validator, 'validation of `{PATH}` failed with value `{VALUE}`');
Error message templates:

从上面的示例中,您可能已经注意到错误消息支持基本的模板。除了 {PATH} 和 {VALUE} 之外,还有一些其他的模板关键字。要了解更多信息,可以在这里找到详细信息

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({
  isAsync: true,
  validator: function (value, respond) {
    doStuff(value, function () {
      ...
      respond(false); // validation failed
    });
  },
  message: 'Custom error message!' // Optional
});

// Can also return a promise
schema.path('name').validate({
  validator: function (value) {
    return new Promise(function (resolve, reject) {
      resolve(false); // validation failed
    });
  }
});

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);
源码
SchemaType.prototype.validate = function(obj, message, type) {
  if (typeof obj === 'function' || obj && utils.getFunctionName(obj.constructor) === 'RegExp') {
    var properties;
    if (message instanceof Object && !type) {
      properties = utils.clone(message);
      if (!properties.message) {
        properties.message = properties.msg;
      }
      properties.validator = obj;
      properties.type = properties.type || 'user defined';
    } else {
      if (!message) {
        message = MongooseError.messages.general.default;
      }
      if (!type) {
        type = 'user defined';
      }
      properties = {message: message, type: type, validator: obj};
    }
    this.validators.push(properties);
    return this;
  }

  var i,
      length,
      arg;

  for (i = 0, length = arguments.length; i < length; i++) {
    arg = arguments[i];
    if (!(arg && utils.getFunctionName(arg.constructor) === 'Object')) {
      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);
  }

  return this;
};

39. connection.js

源码:connection.js

39.1. Connection#close([force], [callback])

Closes the connection

参数:
返回值:
源码
Connection.prototype.close = function(force, callback) {
  var _this = this;
  var Promise = PromiseProvider.get();

  if (typeof force === 'function') {
    callback = force;
    force = false;
  }

  this.$wasForceClosed = !!force;

  return new Promise.ES6(function(resolve, reject) {
    _this._close(force, function(error) {
      callback && callback(error);
      if (error) {
        reject(error);
        return;
      }
      resolve();
    });
  });
};

39.2. Connection#collection(name, [options])

Retrieves a collection, creating it if not cached.

参数:
  • name <String> of the collection

  • [options] <Object> optional collection options

返回值:
  • collection instance

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

源码
Connection.prototype.collection = function(name, options) {
  options = options ? utils.clone(options, { retainKeyOrder: true }) : {};
  options.$wasForceClosed = this.$wasForceClosed;
  if (!(name in this.collections)) {
    this.collections[name] = new Collection(name, this, options);
  }
  return this.collections[name];
};

39.3. Connection(base)

Connection constructor

参数:
  • base <[Mongoose][]> a mongoose instance
继承:
事件:
  • 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 primary and at least one seconaries specified in the connection string are connected.

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

For practical reasons, a Connection equals a Db.

源码
function Connection(base) {
  this.base = base;
  this.collections = {};
  this.models = {};
  this.config = {autoIndex: true};
  this.replica = false;
  this.hosts = null;
  this.host = null;
  this.port = null;
  this.user = null;
  this.pass = null;
  this.name = null;
  this.options = null;
  this.otherDbs = [];
  this.states = STATES;
  this._readyState = STATES.disconnected;
  this._closeCalled = false;
  this._hasOpened = false;
}

39.4. (collection, [options], [callback])

Helper for createCollection(). Will explicitly create the given collection with specified options. Used to create capped collections and views from mongoose.

参数:
  • collection <String> The collection to delete

  • [options] <Object> see MongoDB driver docs

  • [callback] <Function>

返回值:

Options are passed down without modification to the MongoDB driver's createCollection() function

源码
Connection.prototype.createCollection = _wrapConnHelper(function createCollection(collection, options, cb) {
  if (typeof options === 'function') {
    cb = options;
    options = {};
  }
  this.db.createCollection(collection, options, cb);
});

39.5. (collection, [callback])

Helper for dropCollection(). Will delete the given collection, including all documents and indexes.

参数:
返回值:
源码
Connection.prototype.dropCollection = _wrapConnHelper(function dropCollection(collection, cb) {
  this.db.dropCollection(collection, cb);
});

39.6. ([callback])

Helper for dropDatabase(). Deletes the given database, including all collections, documents, and indexes.

参数:

[callback] <Function>

返回值:

<Promise>

源码

Connection.prototype.dropDatabase = _wrapConnHelper(function dropDatabase(cb) {
  this.db.dropDatabase(cb);
});

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

Defines or retrieves a model.

参数:
  • name <String> the model name

  • [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

返回值:
  • The compiled model
参见:
var mongoose = require('mongoose');
var db = mongoose.createConnection(..);
db.model('Venue', new Schema(..));
var Ticket = db.model('Ticket', new Schema(..));
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.

示例:
var schema = new Schema({ name: String }, { collection: 'actor' });

// or

schema.set('collection', 'actor');

// or

var collectionName = 'actor'
var M = conn.model('Actor', schema, collectionName)
源码
Connection.prototype.model = function(name, schema, collection) {
  // collection name discovery
  if (typeof schema === 'string') {
    collection = schema;
    schema = false;
  }

  if (utils.isObject(schema) && !schema.instanceOfSchema) {
    schema = new Schema(schema);
  }
  if (schema && !schema.instanceOfSchema) {
    throw new Error('The 2nd parameter to `mongoose.model()` should be a ' +
      'schema or a POJO');
  }

  if (this.models[name] && !collection) {
    // model exists but we are not subclassing with custom collection
    if (schema && schema.instanceOfSchema && schema !== this.models[name].schema) {
      throw new MongooseError.OverwriteModelError(name);
    }
    return this.models[name];
  }

  var opts = {cache: false, connection: this};
  var model;

  if (schema && schema.instanceOfSchema) {
    // compile a model
    model = this.base.model(name, schema, collection, opts);

    // only the first model with this name is cached to allow
    // for one-offs with custom collection names etc.
    if (!this.models[name]) {
      this.models[name] = model;
    }

    model.init();
    return model;
  }

  if (this.models[name] && collection) {
    // subclassing current model with alternate collection
    model = this.models[name];
    schema = model.prototype.schema;
    var sub = model.__subclass(this, schema, collection);
    // do not cache the sub model
    return sub;
  }

  // lookup model in mongoose module
  model = this.base.models[name];

  if (!model) {
    throw new MongooseError.MissingSchemaError(name);
  }

  if (this === model.prototype.db
      && (!collection || collection === model.collection.name)) {
    // model already uses this connection.

    // only the first model with this name is cached to allow
    // for one-offs with custom collection names etc.
    if (!this.models[name]) {
      this.models[name] = model;
    }

    return model;
  }
  this.models[name] = model.__subclass(this, schema, collection);
  return this.models[name];
};

39.8. Connection#modelNames()

Returns an array of model names created on this connection.

返回值:

<Array>

源码

```
<!--endsec-->

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

Opens the connection to MongoDB.

##### 参数:

  * `connection_string` &lt;[String][]&gt; mongodb://uri or the host to which you are connecting
  * `[database]` &lt;[String][]&gt; database name
  * `[port]` &lt;[Number][]&gt; database port
  * `[options]` &lt;[Object][]&gt; options
  * `[callback]` &lt;[Function][]&gt;


##### 参见:

  * node-mongodb-native
  *
  * http://mongodb.github.com/node-mongodb-native/api-generated/db.html#authenticate


options is a hash with the following possible properties:

<pre>
config  - passed to the connection config instance
db      - passed to the connection db instance
server  - passed to the connection server instance(s)
replset - passed to the connection ReplSet instance
user    - username for authentication
pass    - password for authentication
auth    - options for authentication (see http://mongodb.github.com/node-mongodb-native/api-generated/db.html#authenticate)
</pre>

##### 示例:

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.*

<!--sec data-title="源码" data-id="sec_14" data-show=true data-collapse=true ces-->
```js
Connection.prototype.open = util.deprecate(function() {
  var Promise = PromiseProvider.get();
  var callback;

  try {
    callback = this._handleOpenArgs.apply(this, arguments);
  } catch (error) {
    return new Promise.ES6(function(resolve, reject) {
      reject(error);
    });
  }

  var _this = this;
  var promise = new Promise.ES6(function(resolve, reject) {
    _this._open(true, function(error) {
      callback && callback(error);
      if (error) {
        // Error can be on same tick re: christkv/mongodb-core#157
        setImmediate(function() {
          reject(error);
          if (!callback && !promise.$hasHandler) {
            _this.emit('error', error);
          }
        });
        return;
      }
      resolve();
    });
  });

  // Monkey-patch `.then()` so if the promise is handled, we don't emit an
  // `error` event.
  var _then = promise.then;
  promise.then = function(resolve, reject) {
    promise.$hasHandler = true;
    return _then.call(promise, resolve, reject);
  };

  return promise;
}, '`open()` is deprecated in mongoose >= 4.11.0, use `openUri()` instead, or set the `useMongoClient` option if using `connect()` or `createConnection()`. See http://mongoosejs.com/docs/connections.html#use-mongo-client');

39.9. (uris, [database], [options], [callback])

Opens the connection to a replica set.

参数:
  • uris <String> MongoDB connection string

  • [database] <String> database name if not included in uris

  • [options] <Object> passed to the internal driver

  • [callback] <Function>

参见:
示例:
var db = mongoose.createConnection();
db.openSet("mongodb://user:pwd@localhost:27020,localhost:27021,localhost:27012/mydb");

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.

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

Options passed take precedence over options included in connection strings.

注意:

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

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.

源码
Connection.prototype.openSet = util.deprecate(function(uris, database, options, callback) {
  var Promise = PromiseProvider.get();

  try {
    callback = this._handleOpenSetArgs.apply(this, arguments);
  } catch (err) {
    return new Promise.ES6(function(resolve, reject) {
      reject(err);
    });
  }

  var _this = this;
  var emitted = false;
  var promise = new Promise.ES6(function(resolve, reject) {
    _this._open(true, function(error) {
      callback && callback(error);
      if (error) {
        reject(error);
        if (!callback && !promise.$hasHandler && !emitted) {
          emitted = true;
          _this.emit('error', error);
        }
        return;
      }
      resolve();
    });
  });

  // Monkey-patch `.then()` so if the promise is handled, we don't emit an
  // `error` event.
  var _then = promise.then;
  promise.then = function(resolve, reject) {
    promise.$hasHandler = true;
    return _then.call(promise, resolve, reject);
  };

  return promise;
}, '`openSet()` is deprecated in mongoose >= 4.11.0, use `openUri()` instead, or set the `useMongoClient` option if using `connect()` or `createConnection()`. See http://mongoosejs.com/docs/connections.html#use-mongo-client');

39.10. Connection#collections

A hash of the collections associated with this connection

源码
Connection.prototype.collections;

39.11. Connection#config

A hash of the global options that are associated with this connection

源码
Connection.prototype.config;

39.12. Connection#db

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

源码
Connection.prototype.db;

39.13. Connection#readyState

Connection ready state

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

Each state change emits its associated event name.

示例:
conn.on('connected', callback);
conn.on('disconnected', callback);
源码
Object.defineProperty(Connection.prototype, 'readyState', {
  get: function() {
    return this._readyState;
  },
  set: function(val) {
    if (!(val in STATES)) {
      throw new Error('Invalid connection state: ' + val);
    }

    if (this._readyState !== val) {
      this._readyState = val;
      // loop over the otherDbs on this connection and change their state
      for (var i = 0; i < this.otherDbs.length; i++) {
        this.otherDbs[i].readyState = val;
      }

      if (STATES.connected === val) {
        this._hasOpened = true;
      }

      this.emit(STATES[val]);
    }
  }
});

40. collection.js

源码:collection.js

40.1. Collection(name, conn, opts)

Abstract Collection constructor

参数:

** 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.

源码
function Collection(name, conn, opts) {
  if (opts === void 0) {
    opts = {};
  }
  if (opts.capped === void 0) {
    opts.capped = {};
  }

  opts.bufferCommands = undefined === opts.bufferCommands
      ? true
      : opts.bufferCommands;

  if (typeof opts.capped === 'number') {
    opts.capped = {size: opts.capped};
  }

  this.opts = opts;
  this.name = name;
  this.collectionName = name;
  this.conn = conn;
  this.queue = [];
  this.buffer = this.opts.bufferCommands;
  this.emitter = new EventEmitter();

  if (STATES.connected === this.conn.readyState) {
    this.onOpen();
  }
}

40.2. Collection#createIndex()

驱动程序必须实现的抽象方法。

源码
Collection.prototype.createIndex = function() {
  throw new Error('Collection#ensureIndex unimplemented by driver');
};

40.3. Collection#ensureIndex()

驱动程序必须实现的抽象方法。

源码
Collection.prototype.ensureIndex = function() {
  throw new Error('Collection#ensureIndex unimplemented by driver');
};

40.4. Collection#find()

驱动程序必须实现的抽象方法。

源码
Collection.prototype.find = function() {
  throw new Error('Collection#find unimplemented by driver');
};

40.5. Collection#findAndModify()

驱动程序必须实现的抽象方法。

源码
Collection.prototype.findAndModify = function() {
  throw new Error('Collection#findAndModify unimplemented by driver');
};

40.6. Collection#findOne()

驱动程序必须实现的抽象方法。

源码
Collection.prototype.findOne = function() {
  throw new Error('Collection#findOne unimplemented by driver');
};

40.7. Collection#getIndexes()

驱动程序必须实现的抽象方法。

源码
Collection.prototype.getIndexes = function() {
  throw new Error('Collection#getIndexes unimplemented by driver');
};

40.8. Collection#insert()

驱动程序必须实现的抽象方法。

源码
Collection.prototype.insert = function() {
  throw new Error('Collection#insert unimplemented by driver');
};

40.9. Collection#mapReduce()

驱动程序必须实现的抽象方法。

源码
Collection.prototype.mapReduce = function() {
  throw new Error('Collection#mapReduce unimplemented by driver');
};

40.10. Collection#save()

驱动程序必须实现的抽象方法。

源码
Collection.prototype.save = function() {
  throw new Error('Collection#save unimplemented by driver');
};

40.11. Collection#update()

驱动程序必须实现的抽象方法。

源码
Collection.prototype.update = function() {
  throw new Error('Collection#update unimplemented by driver');
};

40.12. Collection#collectionName

The collection name

源码
Collection.prototype.collectionName;

40.13. Collection#conn

The Connection instance

源码
Collection.prototype.conn;

40.14. Collection#name

The collection name

源码
Collection.prototype.name;
Copyright © tuzhu008 2017 all right reserved,powered by Gitbook该文件修订时间: 2018-01-01 16:05:29

results matching ""

    No results matching ""