Mongoose中文文档-Mongoose的API

 2018年11月16日    755     声明


本文档基于Mongoose官方文档v5.3.12首次发布,适用于MongoDBv3.0+。后续,会根据官方文档更新情况,不定期对本文档进行维护更新。

  1. Mongoose
  2. Schema
  3. Connection
  4. Document
  5. Model
  6. Query
  7. Aggregate
  8. SchemaType
  9. VirtualType
  10. MongooseError
  11. MongooseArray

1. Mongoose

Mongoose()

Mongoose类的构造函数。

mongoose模块的导出(exports)对象是

Mongoose类的一个实例,大多数应用我们只用这一实例即可。

mongoose模块中其它类(如:AggregateModel)包括Mongoose类本身,都是Mongoose类的一个原型属性,我们可以通过实例调用这些类。


Mongoose.prototype.Aggregate()

Mongoose Aggregate类的构造函数。


Mongoose.prototype.CastError()

参数:

  • type <String> 类型名
  • value <Any> 转换失败的值
  • path <String> 发生强制转换错误的doc中的路径a.b.c
  • [reason] <Error> 抛出的原始错误

Mongoose CastError类的构造函数。


Mongoose.prototype.Collection()

Mongoose Collection类的构造函数。


Mongoose.prototype.Connection()

Mongoose Connection类的构造函数。


Mongoose.prototype.Decimal128

Mongoose Decimal128 SchemaTypes。用于在模式(schema)中声明128位十进制浮点的路径。不要用它来创建新的Decimal128实例,而是用mongoose.Types.Decimal128

示例:

const vehicleSchema = new Schema({ fuelLevel: mongoose.Decimal128 });


Mongoose.prototype.Document()

Mongoose Document类的构造函数。


Mongoose.prototype.DocumentProvider()

Mongoose DocumentProvider类的构造函数。开发者不应直接使用这个类。


Mongoose.prototype.Error()

MongooseError 类的构造函数。


Mongoose.prototype.Mixed

Mongoose Mixed SchemaTypes。用于在模式中声明Mongoose的更改跟踪、转换和验证应忽略的路径。

示例

const schema = new Schema({ arbitrary: mongoose.Mixed });


Mongoose.prototype.Model()

Mongoose Model类的构造函数。


Mongoose.prototype.Mongoose()

Mongoose 类的构造函数。

mongoose模块导出的是此类的一个实例。

示例

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


Mongoose.prototype.ObjectId

Mongoose ObjectId SchemaTypes。用于在模式中声明MongoDB ObjectId类型的路径。注意不要直接使用它来创建新的ObjectId实例,而是用mongoose.Types.ObjectId

示例

const childSchema = new Schema({ parentId: mongoose.ObjectId });


Mongoose.prototype.Promise

Mongoose Promise构造函数。


Mongoose.prototype.PromiseProvider

mongoose pomises 的存储层


Mongoose.prototype.Query()

Mongoose Query类的构造函数。


Mongoose.prototype.STATES

向用户空间公开连接状态


Mongoose.prototype.Schema()

Mongoose Schema类的构造函数。

示例

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


Mongoose.prototype.SchemaType()

Mongoose SchemaType类的构造函数。


Mongoose.prototype.SchemaTypes

Mongoose 的各种模式类型

注意:这一属性是mongoose.Schema.Types的别名,用于向后兼容。


Mongoose.prototype.Types

Mongoose 的各种类型

示例

var mongoose = require('mongoose');
var array = mongoose.Types.Array;

Types

  • ObjectId
  • Buffer
  • SubDocument
  • Array
  • DocumentArray

如,我们需要公开访问ObjectId类型,这时可以按需构造ID:

var ObjectId = mongoose.Types.ObjectId;
var id1 = new ObjectId;


Mongoose.prototype.VirtualType()

Mongoose VirtualType类的构造函数。


Mongoose.prototype.connect()

打开默认的mongoose连接。

参数

  • uri(s) <String>
  • [options] <Object> 传递给MongoDB驱动程序的connect()函数,除了以下个单独说明的mongoose特定的选项外,其它参数与MongoDB驱动一致:
    • [dbName] <String> 要使用的数据的名字。如果未提供,数据库名会从连接字符串中获取
    • [user] <String> 认证用户名,等同于options.auth.user。用于保持向后兼容性。
    • [pass] <String> 认证密码,等同于options.auth.password。用于保持向后兼容性。
    • [autoIndex=true] <Boolean> Mongoose 特定选项。设置为false可禁用与此连接关联的所有模型的自动索引创建。
    • [bufferCommands=true] <Boolean> Mongoose 特定选项。设置为false可禁用与此连接关联的所有模型上的缓冲。
    • [useCreateIndex=true] <Boolean> Mongoose 特定选项。如果为true,则此连接将使用createIndex()而不是ensureIndex()通过Model.init()进行自动索引构建。
    • [useFindAndModify=true] <Boolean> 设置为false可以以使findOneAndUpdate()findOneAndRemove()使用本机findOneAndUpdate而不是findAndModify()
    • [useNewUrlParser=false] <Boolean> 设置为true可以使所有连接默认设置为useNewUrlParser选项。
  • [callback] <Function>

返回

  • Promise 如果连接成功,则为resolve状态的`this`

示例

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

// with options
mongoose.connect(uri, options);

// optional callback that gets fired when initial connection completed
var uri = 'mongodb://nonexistent.domain:27000';
mongoose.connect(uri, function(error) {
  // if error is truthy, the initial connection failed.
})


Mongoose.prototype.connection

mongoose模块的默认连接

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

返回

示例

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


Mongoose.prototype.createConnection()

创建一个Connection实例

每个connection实例都映射到一个数据库,同时管理多个数据库连接时,这个方法很有用。

参数

  • uri <String> MongoDB连接字符串,结构:mongodb://URI
  • [options] <Object> 传递给MongoDB驱动程序的connect()函数,除了以下个单独说明的mongoose特定的选项外,其它参数与MongoDB驱动一致:
    • [user] <String> 认证用户名,等同于options.auth.user。用于保持向后兼容性。
    • [pass] <String> 认证密码,等同于options.auth.password。用于保持向后兼容性。
    • [autoIndex=true] <Boolean> Mongoose 特定选项。设置为false可禁用与此连接关联的所有模型的自动索引创建。
    • [bufferCommands=true] <Boolean> Mongoose 特定选项。设置为false可禁用与此连接关联的所有模型上的缓冲。

以上参数中,传递的options中的选项优先于连接字符串中所包含的选项。

返回

  • Connection 所创建的 Connection 对象。该对象是一个 thenable 对象,所以你可以`await mongoose.createConnection()`

示例

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

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

从默认连接中移除名为name的模型,如果存在,您可以使用此函数清除在测试中创建的任何模型,以防发生OverwriteModelErrors错误。

等于mongoose.connection.deleteModel(name)

参数

  • name <String|RegExp> 如果为字符串,则指定名称的模型将被移除。如果为正则表达式,则将移除所有名称匹配到模型。

返回

示例

mongoose.model('User', new Schema({ name: String }));
console.log(mongoose.model('User')); // Model object
mongoose.deleteModel('User');
console.log(mongoose.model('User')); // undefined

// Usually useful in a Mocha `afterEach()` hook
afterEach(function() {
  mongoose.deleteModel(/.+/); // Delete every model
});


Mongoose.prototype.disconnect()

并行运行所有连接上的.close()

参数

  • [callback] <Function> 在所有连接关闭后或第一次发生错误时调用。

返回

  • <Promise> 在所有连接关闭时返回resolve状态,或在发生第一个错误返回reject状态。


Mongoose.prototype.get()

取mongoose的选项设置

参数

  • key <String>

示例

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


Mongoose.prototype.model()

定义或检索模型。

mongoose实例上定义的模型可用于由同一个mongoose实例创建的所有连接。

参数

  • name <String|Function> 模型名或Model的扩展类
  • [schema] <Schema>
  • [collection] <String> 名称(可选,从模型名称推断)
  • [skipInit=false] <Boolean> 是否跳过初始化(默认false

返回

示例

var mongoose = require('mongoose');

// define an Actor model with this mongoose instance
mongoose.model('Actor', new Schema({ name: String }));

// create a new connection
var conn = mongoose.createConnection(..);

// retrieve the Actor model
var Actor = conn.model('Actor');

如果collection参数未传入,Mongoose会使用模型名。如果不想使用模型名,可以传入collection名称、使用mongoose.pluralize()或设置schemas选项中的collection名称。

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

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

返回

  • <Array>

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


Mongoose.prototype.mongo

Mongoose所使用的驱动:node-mongodb-native


Mongoose.prototype.mquery

Mongoose所使用的查询构造器:


Mongoose.prototype.now()

Mongoose使用此函数来设置时间戳(timestamps)时获取当前时间。可以使用像Sinon这样的工具来验证这一功能。


Mongoose.prototype.plugin()

声明在所有Schema上执行的全局插件。

相当于在所创建的每个Schema上调用.plugin(fn)

参数

  • fn <Function> 插件回调函数
  • [opts] <Object> 可选的,选项对象

返回

  • Mongoose 用于复数集合名称的当前函数,默认为来自`mongoose-legacy-pluralize`的遗留函数。


Mongoose.prototype.pluralize()

用于复数集合名称的 Getter/setter 相关函数。

参数

  • fn <Function|null> 重写用于复数集合名称的函数

返回

  • <Function|null> 用于复数集合名称的当前函数,默认为来自`mongoose-legacy-pluralize`的遗留函数。


Mongoose.prototype.set()

设置 mongoose的选(options)项参数

参数

  • key <String>
  • value <String|Function|Boolean>

示例

mongoose.set('test', value) // sets the 'test' option to `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

当前支持的选项参数

  • 'debug': 打印mongoose发送到MongoDB的操作到控制台
  • 'bufferCommands': 启用/禁用 所有连接和模型的mongoose缓冲机制
  • 'useCreateIndex': 默认 false。设置为true则使Mongoose的默认索引构建使用createIndex()而不是ensureIndex()以避免来自MongoDB驱动程序的弃用警告。
  • 'useFindAndModify': 默认 true。设置为false则使findOneAndUpdate()findOneAndRemove()使用原生的findOneAndUpdate()而不是findAndModify()
  • 'useNewUrlParser': 默认 false。设置为true则使所有连接默认设置为useNewUrlParser选项。
  • 'cloneSchemas': 默认 false。设置为trueclone()所有的模式(shema)在编译为模型(model)之前
  • 'applyPluginsToDiscriminators': 默认 false。设置为true则将全局插件应用于鉴别器(Discriminator)模式。通常这是不必要的,因为插件应用于基本模式,并且鉴别器从基础模式复制所有中间件、方法、静态和属性。
  • 'objectIdGetter': 默认 true。Mongoose会为MongoDB ObjectId添加了一个名为_id的getter,为了方便起见,它会返回this。将其设置为false可以删除getter。
  • 'runValidators': 默认 false。设置为true则将为所有验证程序启用更新验证程序
  • 'toObject': 默认 { transform: true, flattenDecimals: true }。将默认对象重写为 toObject()
  • 'toJSON': 默认 { transform: true, flattenDecimals: true }。将默认对象重写到toJSON(),以确定如何通过JSON.stringify()来序列化Mongoose文档。
  • 'strict': 默认 true。可能的值有:truefalse'throw'。设置schema的默认严格模式。
  • 'selectPopulatedPaths': 默认 true。设置为falseMongoose将添加到select()操作的populate()中。schema级的selectPopulatedPaths选项会覆盖此选项。


Mongoose.prototype.startSession()

需要MongoDB >= 3.6.0。启动一个MongoDB会话以使操作保持因果一致性、可重写(Retryable Writes)事务性之类。

调用mongoose.startSession()等同于调用mongoose.connection.startSession()。会话的作用域是一个连接,所以调用mongoose.startSession()会在mongoose默认连接上启动一个会话。

参数

  • [options] <Object> 参考: MongoDb驱动选项
    • [causalConsistency=true] <Boolean> 设置为false则禁用因果一致性
  • [callback] <Function>

返回

  • <Promise<ClientSession>> 包含MongoDB驱动`ClientSession`的resolve状态的promise。


Mongoose.prototype.version

Mongoose 的版本

示例

console.log(mongoose.version); // '5.x.x'


2. Schema


Schema()

Schema 类的构造函数

参数

  • definition <Object>
  • [options] <Object>

options

示例

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

注意,对于在嵌套schema(上例中的children)时,始终是先声明子schema,然后再将其传递给父schema。


Schema.Types

Mongoose Schema 的内置类型

Types

  • <String>
  • <Number>
  • <Boolean|Bool>
  • <Array>
  • <Buffer>
  • <Date>
  • <ObjectId|Oid>
  • <Mixed>

关于内置类型的介绍请参考:


示例

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


Schema.indexTypes

Schema 支持的索引类型

示例

> mongoose.Schema.indexTypes
[ '2d', '2dsphere', 'hashed', 'text' ]


Schema.prototype.add()

将键 path/schema 类型对添加到schema中。

参数

  • obj <Object|Schema>添加的指定路径的普通对象或其他schema
  • [prefix] <String> 指定新添加路径的前缀

返回

  • <Schema> Schema实例。

示例

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

const TurboManSchema = new Schema();
// You can also `add()` another schema and copy over all paths, virtuals,
// getters, setters, indexes, methods, and statics.
TurboManSchema.add(ToySchema).add({ year: Number });


Schema.prototype.childSchemas()

包含子 schema 及与之关联的编译后的 model 的数组。数组中的每个元素都有两个属性:schemamodel

这一属性通常对插件开发者和高级用户有用,一般不需要使用此属性。


Schema.prototype.eachPath()

迭代 schema 的所有路径,类似Array#forEach

每次迭代的回调函数中都包括pathnameschemaType两个参数。

参数

  • [fn] <Function> 回调函数

返回

  • <Schema> this


Schema.prototype.get()

获取 schema 指定名称的选项值

参数

  • key <String> 选项名称


Schema.prototype.index()

为 schema 定义索引

参数

  • fields <Object>
  • [options] <Object> 传递给MongoDB驱动createIndex()函数的选项参数
    • expires=null <String> Mongoose的语法糖,使用ms模块expires选项转换为秒,以设置expireAfterSeconds

示例

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


Schema.prototype.indexes()

返回当前 schema 己定义的索引列表,包括schema.index()定义的和index: true选项中定义的


Schema.prototype.loadClass()

加载一个ES6 Class到 schema 中。并将映射 ES6 Class 中setters\getters静态方法实例方法为 schema virtualsstaticsmethods

示例

const md5 = require('md5');
const userSchema = new Schema({ email: String });
class UserClass {
  // `gravatarImage` becomes a virtual
  get gravatarImage() {
    const hash = md5(this.email.toLowerCase());
    return `https://www.gravatar.com/avatar/${hash}`;
  }

  // `getProfileUrl()` becomes a document method
  getProfileUrl() {
    return `https://mysite.com/${this.email}`;
  }

  // `findByEmail()` becomes a static
  static findByEmail(email) {
    return this.findOne({ email });
  }
}

// `schema` will now have a `gravatarImage` virtual, a `getProfileUrl()` method,
// and a `findByEmail()` static
userSchema.loadClass(UserClass);


Schema.prototype.method()

将实例方法添加到 schema中,所添加的方法将被添加到编译的 Model 构造的 document 中。

参数

  • name <String|Object> 方法名
  • [fn] <Function>

示例

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

可以传入一个 name/fn 对参数,每个 name/fn 对都会被添加到方法中。

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

// later
fizz.purr();
fizz.scratch();

Schema.method()添加的实例方法会被添加到Schema.methods对象中,也可以通过Schema.methods添加,请参考:实例方法


Schema.prototype.obj

传递给 Schema 构造函数的原始对象

示例

var schema = new Schema({ a: String }).add({ b: String });
schema.obj; // { a: String }


Schema.prototype.path()

获取/设置 schema 路径。

参数

  • path <String>
  • constructor <Object>

示例

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


Schema.prototype.pathType()

返回当前 schema path的路径类型,其值可能是:realvirtualnested、或ad-hoc/undefined

参数

  • path <String>

返回

  • <String>


Schema.prototype.plugin()

为当前 schema 注册插件

参数

  • plugin <Function>
  • [opts] <Object>


Schema.prototype.post()

为文档定义一个post钩子

参数

  • method <String|RegExp>
  • [options] <Object>
    • [document] <Boolean> 如果name是文档和查询中间件的钩子,设置为true则在文档中间件上运行。
    • [query] <Object> 如果name是文档和查询中间件的钩子,设置为true则在查询中间件上运行。
  • [fn] <Function> 回调
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 ran a find query');
});

schema.post(/Many$/, function(res) {
  console.log('this fired after you ran `updateMany()` or `deleteMany()`);
});

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

为文档定义一个 pre 钩子

参数

  • method <String|RegExp>
  • [options] <Object>
    • [document] <Boolean> 如果name是文档和查询中间件的钩子,设置为true则在文档中间件上运行。
    • [query] <Object> 如果name是文档和查询中间件的钩子,设置为true则在查询中间件上运行。
  • [fn] <Function> 回调

示例

var toySchema = new Schema({ name: String, created: Date });

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

// Equivalent to calling `pre()` on `find`, `findOne`, `findOneAndUpdate`.
toySchema.pre(/^find/, function(next) {
  console.log(this.getQuery());
});


Schema.prototype.queue()

添加一个方法调用到调用队列中

参数

  • name <String> 稍后调用的文档方法的名称
  • args <Array> 传递给方法的参数


Schema.prototype.requiredPaths()

返回此 schema 所需的路径字符串数组。

参数

  • invalidate <Boolean> 刷新缓存

返回

  • <Array>


Schema.prototype.set()

设置/获取 schema 的选项设置

参数

  • key <String> 选项名
  • [value] <Object> 设置值。不传入则返回当前设置值

示例

schema.set('strict'); // 'true' by default
schema.set('strict', false); // Sets 'strict' to false
schema.set('strict'); // 'false'


Schema.prototype.static()

添加静态类方法到 Schema 所编译的 Model 中

参数

  • name <String|Object>
  • [fn] <Function>

示例

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

当传入一个 name/fn 对对象时,所有 name/fn 对都将被添加为静态方法


Schema.prototype.virtual()

通过指定的name创建一个虚拟类型

参数

  • name <String>
  • [options] <Object>

返回

  • <VirtualType>


Schema.prototype.virtualpath()

返回指定name的虚拟类型

参数

  • name <String>

返回

  • <VirtualType>


Schema.prototype.reserved

Schema 的保留文档键。这些键是在声明 schema 时不能使用,与mongoose功能冲突。 使用这些键名将引发错误。

'_posts', '_pres', 'remove', 'validate', 'toObject', 'schema', 'save', 'modelName', 'get', 'isNew', 'isModified', 'init', 'errors', 'db', 'collection', 'removeListener', 'listeners', 'once', 'on', 'emit', 'prototype' 

注意,这些键名可以做为方法名,但会有一定的风险,因为它们可能是 mongoose 的文档方法。

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


3. Connection


Connection()

Connection 的构造函数。在实际使用中,Connection等于Db。

参数


Connection.prototype.close()

关闭连接

参数

  • [force] <Boolean> 是否强制关闭
  • [callback] <Function> 回调函数

返回

  • <Connection> self


Connection.prototype.collection()

检索指定名称的集合,如果没有缓存则创建。应用一般不需要,只需通过Model与Collection会话。

参数

  • name <String> 连接名
  • [options] <Object> 连接设置选项

返回

  • <Connection> Connection 实例


Connection.prototype.collections

与当前连接关联的所有集合的哈希


Connection.prototype.config

与当前连接关联的所有集合的哈希


Connection.prototype.createCollection()

调用MongoDB 驱动的createCollection()函数,用于从mongoose创建capped collectionview

参数

  • collection <String> 要创建的集合
  • [options] <Object> 设置选项,见:MongoDB 驱动文档
  • [callback] <Function> 回调函数

返回

  • <Pormise>


Connection.prototype.config

mongodb.Db实例,在打开连接时设置


Connection.prototype.deleteModel()

从当前连接中移除名为name的模型。如果存在,可以使用此函数清除在测试时创建的任何模型,以防止OverwriteModelErrors

参数

  • name <String|RegExp> 字符串模型名或正则表达式。当为正则表达式时,将移队所有匹配到的模型

返回

  • <Connection> this

示例

conn.model('User', new Schema({ name: String }));
console.log(conn.model('User')); // Model object
conn.deleteModel('User');
console.log(conn.model('User')); // undefined

// Usually useful in a Mocha `afterEach()` hook
afterEach(function() {
  conn.deleteModel(/.+/); // Delete every model
});


Connection.prototype.dropCollection()

删除指定的集合,包括所有文档和索引。

参数

  • collection <String> 要删除的集合名
  • [callback] <Function> 回调函数

返回

  • <Promise>


Connection.prototype.dropDatabase()

删除指定的数据库,包括所有集合、文档和索引。

参数

  • [callback] <Function> 回调函数

返回

  • <Promise>


Connection.prototype.host

URI的主机名部分。如果有多个主机(例如副本集),则将是包含URI中的第一个主机名

示例

mongoose.createConnection('mongodb://localhost:27017/mydb').host; // "localhost"


Connection.prototype.model()

定义或获取一个模型

参数

  • name <String|Function> 模型名或Model的扩展类
  • [schema] <Schema> schema,定义模型时必需
  • [collection] <String> mongodb 集合名,不指定时将从模型名中获取

返回

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

当未传入collection参数时,Mongoose会将模型name传递给utils.toCollectionName方法来生成集合名称。该方法会使名称多元化,如果不喜欢这样,请传递集合名称或设置schema的集合名称选项。

示例

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

当前连接中所创建的所有模型名称的列表

返回

  • <Array>


Connection.prototype.name

当前连接所指向数据库的名称

示例

mongoose.createConnection('mongodb://localhost:27017/mydb').name; // "mydb"


Connection.prototype.pass

URI中指定的密码

示例

mongoose.createConnection('mongodb://val:psw@localhost:27017/mydb').pass; // "psw"


Connection.prototype.port

URI中指定的端口。如果有多个主机(例如副本集),则返回包含URI中第一个主机名的端口。

示例

mongoose.createConnection('mongodb://localhost:27017/mydb').port; // 27017


Connection.prototype.readyState

连接的就绪状态:

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

每次状态更改会发出与其关联的事件名称。

示例

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


Connection.prototype.startSession()

需要MongoDB >= 3.6.0。启动一个MongoDB会话以使操作保持因果一致性、可重写(Retryable Writes)事务性

参数

  • [options] <Object> 参考: MongoDb驱动选项
    • [causalConsistency=true] <Boolean> 设置为false则禁用因果一致性
  • [callback] <Function>

返回

  • <Promise<ClientSession>> 包含MongoDB驱动`ClientSession`的resolve状态的promise。

示例

const session = await conn.startSession();
let doc = await Person.findOne({ name: 'Ned Stark' }, null, { session });
await doc.remove();
// `doc` will always be null, even if reading from a replica set
// secondary. Without causal consistency, it is possible to
// get a doc back from the below query if the query reads from a
// secondary that is experiencing replication lag.
doc = await Person.findOne({ name: 'Ned Stark' }, null, { session, readPreference: 'secondary' });


Connection.prototype.useDb()

使用相同的连接池切换到其他数据库,并返回所要使用新db的新连接对象。

参数

  • name <String> 数据库名

返回

  • <Connection> 连接对象


Connection.prototype.user

RUI 中的用户名部分

mongoose.createConnection('mongodb://val:psw@localhost:27017/mydb').user; // "val"


4. Document


Document.prototype.$ignore()

不在此路径上运行验证或将更改保留到此路径。

参数

  • path <String> 要忽略的路径

示例

doc.foo = null;
doc.$ignore('foo');
doc.save(); // changes to foo will not be persisted and validators won't be run


Document.prototype.$isDefault()

检查路径是否是默认值

参数

  • [path] <String>

返回

  • <Boolean>

示例

MyModel = mongoose.model('test', { name: { type: String, default: 'Val '} });
var m = new MyModel();
m.$isDefault('name'); // true


Document.prototype.$isDeleted()

Getter/setter,确定文档是否已删除。

参数

  • [val] <Boolean> 重写 mongoose 是否认为该文档已删除

返回

  • <Boolean> mongoose 认为此文档是否已删除

示例

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

将路径标记为有效,从而删除现有的验证错误。

参数

  • path <String> 要标记为有效的字段


Document.prototype.$session()

与此文档关联会话的 Getter/setter。 如果save()有关联会话的query中获取的文档,则用于自动设置session

参数

  • [session] <ClientSession> 重写当前会话

返回

  • <ClientSession>
const session = MyModel.startSession();
const doc = await MyModel.findOne().session(session);
doc.$session() === session; // true
doc.$session(null);
doc.$session() === null; // true

如果当前文档是一个顶级文档,此会话会应用到所有子文档


Document.prototype.$set()

set方法的别名,以避免内部冲突。

参数

  • path <String|Object> 要设置key/vals对的路径或对象
  • val <Any> 要设置的值
  • [type] <Schema|String|Number|Buffer|*> 可选,为动态属性指定类型要
  • [options] <String|Object> 指定修改集合行为的选项


Document.prototype.depopulate()

填充(populate)字段将其返回到未填充状态;如果路径未填充,则无操作。

参数

  • path <String>

返回

  • <Document> this

示例

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


Document.prototype.equals()

如果已存储的Document与要对比的doc相同,则返回true

当两个文档的_id相同时,则认为是匹配的;如果两个文档都没有_id,则会使用deepEqual()对比。

参数

  • doc <Document> 要对比的文档

返回

  • <Boolean> this


Document.prototype.errors()

包含当前验证错误的哈希。


Document.prototype.execPopulate()

执行填充(populate)并返回Promise。

参数

  • [callback] <Function> 可选回调函数,传入后将不在返回Promise

返回

  • <Promise> 填充完成后解析的文档

示例

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

执行填充(populate)并返回Promise。

参数

  • [callback] <Function> 可选回调函数,传入后将不在返回Promise

返回

  • <Promise> 填充完成后解析的文档

示例

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

返回路径所对应的值。

参数

  • path <String>
  • [type] <Schema|String|Number|Buffer|*> 为动态属性指定类型

示例

// path
doc.get('age') // 47

// dynamic casting to a string
doc.get('age', String) // "47"


Document.prototype.id

文档_id的字符串版本

默认情况下,此getter存在于所有文档中。可以在构造时将其Schemaid选项设置为false来禁用getter。

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


Document.prototype.init()

在没有setter的情况下初始化文档或标记要修改的内容。从mongoDB返回文档后会在内部进行调用,通常不需要自己调用此函数。

参数

  • doc <Object> MongoDB返回的文档

此函数会触发init中间件。注意,这个init钩子函数是同步的。


Document.prototype.inspect()

console.log的helper


Document.prototype.invalidate()

将路径标记为无效,导致验证失败。

参数

  • path <String> 要验证的字段
  • errorMsg <String|Error> 验证无效时的错误说明
  • [value] <Object|String|Number|any> 可选的无效值
  • [kind] <String> 可选的,错误的种类属性

返回

  • <ValidationError> 当前的ValidationError,包含当前所有无效的路径
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.isDirectModified()

参数

  • path <String>

返回

  • <Boolean>

如果直接设置和修改path,则返回true,否则返回false

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


Document.prototype.isDirectSelected()

检查是否直接选择了path。 如果没有映射,则始终返回true

参数

  • path <String>

返回

  • <Boolean>

示例

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

检查path是否已初始化。

参数

  • path <String>

返回

  • <Boolean>


Document.prototype.isModified()

检查是否修改过,如果修改过则返回true,否则返回false。 如果没有映射,则始终返回true

如果提供path参数,则检查路径或包含path作为其路径链的一部分的完整路径是否已被修改。

参数

  • [path] <String>

返回

  • <Boolean>

示例

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

返回一个布尔值,标识文档是否是新的。

返回

  • <Boolean>


Document.prototype.isSelected()

检查在初始化此文档的源查询中是否选择了路径path参数。

参数

  • path <String>

返回

  • <Boolean>

示例

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


Document.prototype.markModified()

path标记为待更改状态以写入数据库。

参数

  • path <String> 标记更改的路径
  • [scope] <Document> 运行验证器的范围

注意:这一方法在Mixed类型中非常有用,Mixed类型的数据不会标注为更改状态,调用.save()方法也不能保存到数据库,这时就需要使用本方法手动更新状态。

示例

doc.mixed.type = 'changed';
doc.markModified('mixed.type');
doc.save() // 现在对 mixed.type 的修改就可以持久化到数据库中了


Document.prototype.modifiedPaths()

返回已修改的路径列表。

参数

  • [options] <Object>
    • [includeChildren=false] <Boolean> 如果为true,则返回修改路径的子节点。

      例如,如果为falsedoc.colors = { primary: 'blue' };的修改列表中将不包含colors.primary;如果为true则包含colors.primary

返回

  • <Array>


Document.prototype.populate()

填充文档引用,并完成后执行callback。 如果想使用Promise,请使用execPopulate()函数。

参数

  • [path] <String|Object> 要填充文档的路径或对象
  • [callback] <Function> 传入后,会在填充完成后调用

返回

  • <Boolean>

注意,除非传入callback或显式调用execPopulate(),否则不会进行填充。第二次传递相同的路径将覆盖以前的路径选项。相关关选项的说明,请参见Model.populate()

示例

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


Document.prototype.populated()

获取在指定path填充期间所使用的 _id(s)。

参数

  • path <String>

返回

  • <Array,ObjectId,Number,Buffer,String,undefined>

如果path没有填充,会返回undefined

示例

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


Document.prototype.replaceOne()

以当前文档_id作为查询选择器发送replaceOne命令。

参数

  • doc <Object>
  • options <Object>
  • callback <Function>

返回

验证选项参考:Model.replaceOne


Document.prototype.save()

保存当前文档。

参数

  • [options] <Object>
    • safe <Object> (弃用),重写schema的safe选项
    • validateBeforeSave <Boolean> 设置为false则保存时不验证
  • callback <Function>

回调函数中会包含以下两个参数:

  • err <Error> 发生错误时会传入
  • document <Document> 保存后的文档

返回

  • <Promise,undefined> 传入callback返回undefined,否则返回Promise

示例

product.sold = Date.now();
product.save(function (err, product) {
  if (err) ..
})

不传入传入callbacksave将返回Promise

product.save().then(function(product) {
   ...
});


Document.prototype.schema

当前文档所对应的schema


Document.prototype.set()

设置一或多个path的值。

参数

  • path <String|Object> 要设置的path或key/vals对象
  • val <Any> 要设置的值
  • [type] <Schema|String|Number|Buffer|*> 为“动态”属性指定的类型
  • [options] <Object> 指定修改集合行为的选项

示例

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

将此方法的返回值用于JSON.stringify(doc)调用。

参数

  • options <Object>

返回

  • <options>

此方法接受与Document#toObject相同的选项参数。 要在默认情况下将选项应用于schema的每个文档,所以请将schematoJSON选项设置为相同的参数。

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

参考:schema options


Document.prototype.toObject()

将文档转换为普通的JavaScript对象,以适合在MongoDB存储。

参数

  • options <Object>
    • getters=false <Boolean> 设置为true,将应用到所有getters,包括虚拟getter(virtuals)
    • virtuals=false <Boolean> 设置为true,将应用到virtuals。设置为{ getters: true, virtuals: false }将仅应用于gettes,而不包括virtuals
    • minimize=true <Boolean> 设置为true,将省略输出中的任何空对象
    • transform=null <Function|null> 如果设置本选项,mongoose将调用此函数以使你可以转换返回的对象
    • depopulate=false <Boolean> 设置为true,将用输出中的原始id替换任何常规填充的路径,对虚拟填充路径没有影响
    • versionKey=true <Boolean> 设置为false,输出中将不包括版本标识(默认为__v

返回

  • <Object>

mongodb.Binary

缓冲区转换为mongodb.Binary的实例以进行适当的存储。


Document.prototype.toString()

console.log的helper。


Document.prototype.unmarkModified()

清除指定path的修改状态。

参数

  • path <String> 清除修改的路径

示例

doc.foo = 'bar';
doc.unmarkModified('foo');
doc.save(); // changes to foo will not be persisted


Document.prototype.update()

使用此文档的_id作为查询选择器发送update命令。

参数

  • doc <Object>
  • options <Object> 参考Model.update
  • callback <Function>

返回

  • <Query>
weirdCar.update({$inc: {wheels:1}}, { w: 1 }, callback);


Document.prototype.updateOne()

使用此文档的_id作为查询选择器发送updateOne命令。

参数

返回

  • <Query>
weirdCar.updateOne({$inc: {wheels:1}}, { w: 1 }, callback);


Document.prototype.validate()

执行本文档已注册的验证规则。

参数

  • [options] <Object>
  • [callback] <Function> 回调函数,如果发生错误则会传递错误

返回

  • <Promise>

本方法可以认为是预保存,如果违反验证规则,则会中止保存并将错误传给callback

doc.validate(function (err) {
  if (err) handleError(err);
  else // validation passed
});


Document.prototype.validateSync()

执行此文档已注册的验证规则(跳过异步验证程序)。

参数

  • pathsToValidate <Array|string> 仅验证所指定的路径

返回

  • <MongooseError,undefined> 验证失败将返回 MongooseError,否则返回undefined

示例

var err = doc.validateSync();
if ( err ){
  handleError( err );
} else {
  // validation passed
}


5. Model


Model()

Model是一个与MongoDB交互的主要工具。Model类的实例是一个Document,也就是说Model的所有实例方法或属性(Model.prototype.*)都是对文档的操作。

参数

  • doc <Object> 初始化值
  • [fields] <Object> 返回查询此文档要选择的字段对象。一般无需设置此参数,以便Mongoose可以正确处理你的查询映射

在Mongoose中,术语"Model"指的是mongoose.Model类的子类。不应该直接使用mongoose.Model类,而且使用mongoose.model()connection.model()函数来创建mongoose.Model的子类。如下所示:

// `UserModel` is a "Model", a subclass of `mongoose.Model`.
const UserModel = mongoose.model('User', new Schema({ name: String }));

// You can use a Model to create new documents using `new`:
const userDoc = new UserModel({ name: 'Foo' });
await userDoc.save();

// You also use a model to create queries:
const userFromDb = await UserModel.findOne({ name: 'Foo' });


Model.aggregate()

对模型的集合执行聚合操作。

参数

  • [pipeline] <Array> 聚合管道组成的对象数组
  • [callback] <Function>

返回

如果传入callback,则会执行aggregate并返回一个Promise;如果未传入callback,则返回aggregate本身。

这个函数会触发aggregate中间件。

示例

// Find the max balance of all accounts
Users.aggregate([
  { $group: { _id: null, maxBalance: { $max: '$balance' }}},
  { $project: { _id: 0, maxBalance: 1 }}
]).
then(function (res) {
  console.log(res); // [ { maxBalance: 98000 } ]
});

// Or use the aggregation pipeline builder.
Users.aggregate().
  group({ _id: null, maxBalance: { $max: '$balance' } }).
  project('-id maxBalance').
  exec(function (err, res) {
    if (err) return handleError(err);
    console.log(res); // [ { maxBalance: 98 } ]
  });

使用本方法时需注意:

  • 参数不会转换为模型的模式(schema),因为$project运算符允许在管道的任何阶段重新定义文档的“形状”,以使文档保持不兼容的格式。
  • 返回的文档是普通的javascript对象,而不是mongoose文档(因为可能返回的文档格式不固定)。
  • 需要MongoDB> = 2.1


Model.bulkWrite()

在一个命令中向MongoDB发送insertOne, updateOne, updateMany, replaceOne, deleteOne, 和/或 deleteMany 操作命令。这比发送多个独立操作更快,因为bulkWrite()只有一次与MongoDB的交互。

调用本方法后,Mongoose会对所发送的所有操作进行转换。

参数

  • ops <Array>
  • [options] <Object>
  • [callback] <Function> 回调函数,格式为:function(error, bulkWriteOpResult) {}

返回

  • <Promise>

注意,这一方法不会触发任何中间件,如:save()update()。如果需要触发save()中间件,就要在每个文档上使用create()

示例

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


Model.count()

统计与数据库集合中的filter所匹配的文档数。

参数

  • filter <Object>
  • [callback] <Function>

返回

  • <Query>

不推荐使用此方法。如果要计算集合中的文档数,如count({}),请使用estimatedDocumentCount()函数代替,或使用countDocuments()函数。

示例

Adventure.count({ type: 'jungle' }, function (err, count) {
  if (err) ..
  console.log('there are %d jungle adventures', count);
});


Model.countDocuments()

统计与数据库集合中的filter所匹配的文档数。

参数

  • filter <Object>
  • [callback] <Function>

返回

  • <Query>

示例

Adventure.countDocuments({ type: 'jungle' }, function (err, count) {
  console.log('there are %d jungle adventures', count);
});

请注意,如果要统计大型集合中的所有文档,请使用estimatedDocumentCount()函数,如果使用countDocuments()函数MongoDB将始终执行完整的集合扫描而不使用任何索引。

countDocuments()函数类似于count(),但支持一些countDocuments()不支持的运算符

以下是count()countDocuments()不支持的运算符及替换建议:

  • $where$expr
  • $near$geoWithin$center
  • $nearSphere$geoWithin$centerSphere


Model.create()

将一个或多个文档保存到数据库的快捷操作。

参数

  • docs <Array|Object> 要插入的文档,展开的独立对象或数组
  • [options] <Object> 传递给save()的选项。要指定本选项,docs必须是数组,而不是展开对象
  • [callback] <Function>

返回

  • <Promise>

使用本方法时,MyModel.create(docs)会为为docs中的每个doc创建新的MyModel(doc).save()

本方法会触发save()中间件

示例

// pass a spread of docs and a callback
Candy.create({ type: 'jelly bean' }, { type: 'snickers' }, function (err, jellybean, snickers) {
  if (err) // ...
});

// pass an array of docs
var array = [{ type: 'jelly bean' }, { type: 'snickers' }];
Candy.create(array, function (err, candies) {
  if (err) // ...

  var jellybean = candies[0];
  var snickers = candies[1];
  // ...
});

// callback is optional; use the returned promise if you like:
var promise = Candy.create({ type: 'jawbreaker' });
promise.then(function (jawbreaker) {
  // ...
})


Model.createCollection()

为当前模型创建集合。默认情况下,如果未指定索引,则在创建任一文档之前,mongoose不会为模型创建集合。

参数

使用本方法请注意以下两点:

  1. 需要在开始事务(transaction)之前调用本方法:Transactions and Operations
  2. 如果schema中包含了indexunique字段,则不用调用些方法,仅需使用Model.init()

示例

var userSchema = new Schema({ name: String })
var User = mongoose.model('User', userSchema);

User.createCollection().then(function(collection) {
  console.log('Collection is created!');
});


Model.createIndexes()

类似ensureIndexes,但本方法使用createIndex函数。

参数

  • [options] <Object> 内部选项
  • [callback] <Function>

返回

  • <Promise>


Model.deleteMany()

删除与集合中conditions匹配的所有文档。类似于remove(),但删除所有匹配conditions的文档,而忽略single选项。

参数

返回

  • <Query>

示例

Character.deleteMany({ name: /Stark/, age: { $gte: 18 } }, function (err) {});

注意,类似于Model.remove(),本方法不会触发pre('remove')ost('remove')


Model.deleteOne()

删除与集合中conditions所匹配的第一文档。类似于remove(),但无论single选项如何,仅会删除一个文档。

参数

  • conditions <Object> 内部选项
  • [callback] <Function>

返回

  • <Query>

示例

Character.deleteOne({ name: 'Eddard Stark' }, function (err) {});

注意,类似于Model.remove(),本方法不会触发pre('remove')ost('remove')


Model.discriminator()

添加鉴别器类型。

参数

  • name <String> 鉴别器模型名
  • schema <Schema> 鉴别器模型的schema
  • value <String> 存储在discriminatorKey属性中的字符串

返回

  • <Query>

示例

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);
new Boss().__t; // "Boss". `__t` is the default `discriminatorKey`

var employeeSchema = new Schema({ boss: ObjectId });
var Employee = Person.discriminator('Employee', employeeSchema, 'staff');
new Employee().__t; // "staff" because of 3rd argument above


Model.distinct()

distinct操作创建查询。

参数

  • field <String>
  • [conditions] <Schema>
  • [callback] <Function>

传入callback时会立即执行查询。

返回

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


Model.ensureIndexes()

为schema中声明的每个索引发送MongoDB的createIndex命令,createIndex命令会串行发送。

参数

  • [options] <Object>
  • [callback] <Function>

返回

  • <Promise>
Event.ensureIndexes(function (err) {
  if (err) return handleError(err);
});

完成后,在此Model上发出index事件,如果发生错误则传递错误。

示例

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

注意:在生产中谨慎使用。根据负载情况的不同,索引创建可能会影响数据库性能。


Model.estimatedDocumentCount()

估算MongoDB集合中的文档数量。在大型集合中会比使用countDocuments()更快,因为estimatedDocumentCount()使用集合元数据而不是扫描整个集合。

参数

  • [options] <Object>
  • [callback] <Function>

返回

  • <Query>
const numAdventures = Adventure.estimatedDocumentCount();


Model.find()

查找文档。

参数

返回

  • <Query>

在发送命令之前,conditions会转换为各自的SchemaTypes。

示例

// named john and at least 18
MyModel.find({ name: 'john', age: { $gte: 18 }});

// executes immediately, passing results to callback
MyModel.find({ name: 'john', age: { $gte: 18 }}, function (err, docs) {});

// name LIKE john and only selecting the "name" and "friends" fields, executing immediately
MyModel.find({ name: /john/i }, 'name friends', function (err, docs) { })

// passing options
MyModel.find({ name: /john/i }, null, { skip: 10 })

// passing options and executing immediately
MyModel.find({ name: /john/i }, null, { skip: 10 }, function (err, docs) {});

// executing a query explicitly
var query = MyModel.find({ name: /john/i }, null, { skip: 10 })
query.exec(function (err, docs) {});

// using the promise returned from executing a query
var query = MyModel.find({ name: /john/i }, null, { skip: 10 });
var promise = query.exec();
promise.addBack(function (err, docs) {});


Model.findById()

通过_id字段查找单个文档。

参数

返回

  • <Query>

findById(id)等同于findOne({ _id: id }),如果你想通过_id来查找一个文档,请findById()来代替findOne()

在向MongoDB发送命令前,会基于Schema强制转换id

本方法会触发findOne()中间件。

示例

// find adventure by id and execute immediately
Adventure.findById(id, function (err, adventure) {});

// same as above
Adventure.findById(id).exec(callback);

// select only the adventures name and length
Adventure.findById(id, 'name length', function (err, adventure) {});

// same as above
Adventure.findById(id, 'name length').exec(callback);

// include all properties except for `length`
Adventure.findById(id, '-length').exec(function (err, adventure) {});

// passing options (in this case return the raw js objects, not mongoose documents by passing `lean`
Adventure.findById(id, 'name', { lean: true }, function (err, doc) {});

// same as above
Adventure.findById(id, 'name').lean().exec(function (err, doc) {});


Model.findByIdAndDelete()

通过_id字段查找单个文档并删除。

参数

返回

  • <Query>

本方法会通过文档的_id字段发出MongoDB的findOneAndDelete()命令。可以认为findByIdAndDelete(id)findOneAndDelete({_ id:id})的简写。

本方法会触发findOneAndDelete()中间件。


Model.findByIdAndRemove()

通过_id字段查找文档并删除,并将匹配的文档(如果有)传递给回调函数。

参数

  • id <Object|String|Number> 要查询的文档_id
  • [options] <Object> 参见:Query.prototype.setOptions()
    • sort <Object> 如果找到多个文档,则按设置的排序顺序选择要更新的文档
    • select <Object|String> 设置要返回的文档字段
    • rawResult <Boolean> 如果为true,则返回MongoDB驱动程序的原始结果
    • strict <Boolean> :覆盖此更新的schema的严格模式选项
  • [callback] <Function>

返回

  • <Query>

本方法会向MongoDB发送findAndModify删除命令。findByIdAndRemove(id,...)方法等同于findOneAndRemove({_ id:id},...)方法

传入callback函数会立即执行,否则返回一个Query对象

本方法会触发findOneAndRemove()中间件。

示例

A.findByIdAndRemove(id, options, callback) // executes
A.findByIdAndRemove(id, options)  // return Query
A.findByIdAndRemove(id, callback) // executes
A.findByIdAndRemove(id) // returns Query
A.findByIdAndRemove()           // returns Query


Model.findByIdAndUpdate()

通过_id字段查找单个文档并更新。

参数

  • id <Object|String|Number> 要查询的文档_id
  • [update] <Object>
  • [options] <Object> 参见:Query.prototype.setOptions()
    • [new=false] <Boolean> 设置为true将返回修改后的文档,否则返回原始文档
    • [upsert=false] <Boolean> 设置为true,如果不存在则创建新对象
    • [runValidators] <Boolean> 设置为true,则在此命令上运行更新验证器。更新验证器会根据模型的schema验证更新操作。
    • [setDefaultsOnInsert=false] <Boolean> 本项及upsert设置为true,如果创建了新文档,mongoose将应用模型架构(schema)中指定的默认值MongoDB> = 2.4适用,因为它依赖于MongoDB的$setOnInsert运算符
    • [select] <Object|String> 设置要返回的文档字段
    • [rawResult=false] <Boolean> 设置为true将返回MongoDB驱动的原始值
    • [strict=false] 覆盖此更新的schema的严格模式选项
  • [callback] <Function>

返回

  • <Query>

本方法会向MongoDB发送findAndModify删除命令。findByIdAndUpdate(id,...)方法等同于findOneAndUpdate({_ id:id},...)方法

查找匹配的文档,并根据update参数进行更新,并将找到的文档(如果有)返回给回调。如果传递回调,则立即执行查询,否则返回Query对象。

本方法会触发findOneAndUpdate()中间件。

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

注意:所有非原子(atomic)的操作名称的顶级键更新都会被视为set操作:

Model.findByIdAndUpdate(id, { name: 'jason bourne' }, options, callback)

// is sent as
Model.findByIdAndUpdate(id, { $set: { name: 'jason bourne' }}, options, callback)

使用findAndModify的帮助程序时,会将值转换为适当的类型。但默认情况下不执行以下操作:

  • defaults 使用setDefaultsOnInsert选项覆盖

findAndModify的帮助程序支持有限的验证,可以通过设置runValidators选项来启用.


Model.findOne()

查找单个文档。

参数

返回

  • <Query>

在向MongoDB发送命令前,conditions将转换为各自的SchemaTypes。

注意:conditions是可选条件,如果未传入则会向MongoDB发送一个空的findOne命令,这可能会返回任意一个文档。

示例

// find one iphone adventures - iphone adventures??
Adventure.findOne({ type: 'iphone' }, function (err, adventure) {});

// same as above
Adventure.findOne({ type: 'iphone' }).exec(function (err, adventure) {});

// select only the adventures name
Adventure.findOne({ type: 'iphone' }, 'name', function (err, adventure) {});

// same as above
Adventure.findOne({ type: 'iphone' }, 'name').exec(function (err, adventure) {});

// specify options, in this case lean
Adventure.findOne({ type: 'iphone' }, 'name', { lean: true }, callback);

// same as above
Adventure.findOne({ type: 'iphone' }, 'name', { lean: true }).exec(callback);

// chaining findOne queries (same as above)
Adventure.findOne({ type: 'iphone' }).select('name').lean().exec(callback);


Model.findOneAndDelete()

查找一个匹配的文档,删除,并将该文档传入回调函数(如果有)中。

参数

  • conditions <Object>
  • [options] <Object> 参见:Query.prototype.setOptions()
    • [sort] <Object> 如果找到多个文档,则按设置的排序顺序选择要更新的文档
    • maxTimeMS Number 设置查询时间限制,需要mongodb> = 2.6.0
    • [select] <Object|String> 设置要返回的文档字段
    • [projection] <Object> 类似select,用于确定要返回的字段,如:{ projection: { _id: 0 } }
    • [rawResult=false] <Boolean> 设置为true将返回MongoDB驱动的原始值
    • [strict=false] 覆盖此更新的schema的严格模式选项
  • [callback] <Function>

返回

  • <Query>

等同于MongoDB的findOneAndDelete()命令。

传入callback函数会立即执行,否则返回一个Query对象

本方法会触发findOneAndDelete()中间件。

本方法与Model.findOneAndRemove()稍有不同,因为findOneAndRemove()在变为MongoDB中findAndModify()命令,而不是findOneAndDelete()命令。对于大多数mongoose用例而言,不用做这些区分,更应该使用findOneAndDelete()

示例

A.findOneAndDelete(conditions, options, callback) // executes
A.findOneAndDelete(conditions, options)  // return Query
A.findOneAndDelete(conditions, callback) // executes
A.findOneAndDelete(conditions) // returns Query
A.findOneAndDelete()           // returns Query

使用findAndModify的帮助程序时,值将转换为适当的类型。默认情况下不执行以下操作:

  • defaults - 使用setDefaultsOnInsert选项覆盖。

findAndModify的帮助程序支持有限的验证,可以通过runValidators选项来启动

Model.findById(id, function (err, doc) {
  if (err) ..
  doc.name = 'jason bourne';
  doc.save(callback);
});


Model.findOneAndRemove()

查找一个匹配文档并删除,并将匹配的文档(如果有)传递给回调函数。

参数

  • conditions <Object>
  • [options] <Object> 参见:Query.prototype.setOptions()
    • [sort] <Object> 如果找到多个文档,则按设置的排序顺序选择要更新的文档
    • maxTimeMS Number 设置查询时间限制,需要mongodb> = 2.6.0
    • [select] <Object|String> 设置要返回的文档字段
    • [projection] <Object> 类似select,用于确定要返回的字段,如:{ projection: { _id: 0 } }
    • [rawResult=false] <Boolean> 设置为true将返回MongoDB驱动的原始值
    • [strict=false] 覆盖此更新的schema的严格模式选项
  • [callback] <Function>

返回

  • <Query>

等同于MongoDB的findAndModify命令。

传入callback函数会立即执行,否则返回一个Query对象

本方法会触发findOneAndRemove()中间件。

示例

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

使用findAndModify的帮助程序时,值将转换为适当的类型。默认情况下不执行以下操作:

  • defaults - 使用setDefaultsOnInsert选项覆盖。

findAndModify的帮助程序支持有限的验证,可以通过runValidators选项来启动

Model.findById(id, function (err, doc) {
  if (err) ..
  doc.name = 'jason bourne';
  doc.save(callback);
});


Model.findOneAndUpdate()

查找一个匹配的文档,并按update参数对其更新,同时可传入任何options所支持的参数,并将找到的文档传入回调函数(如果有)中。

参数

  • [conditions] <Object>
  • [update] <Object>
  • [options] <Object> 参见:Query.prototype.setOptions()
    • [lean=false] <Boolean> 设置为true,则返回普通的JavaScript对象,否则返回mongoose文档。参见:Query.lean()
    • [new=false] <Boolean> 设置为true,返回修改后的文档而不是原始文档。默认true(修改于v4.0
    • [upsert=false] <Boolean> 设置为true时,如果文档不存在则创建文档。
    • [fields] <Object|String> 字段筛选,等同于.select(fields).findOneAndUpdate()
    • [sort] <Object> 如果找到多个文档,则按设置的排序顺序选择要更新的文档
    • maxTimeMS Number 设置查询时间限制,需要mongodb> = 2.6.0
    • [runValidators=false] <Boolean> 设置为true,则在此命令上运行更新验证器。更新验证器会根据模型的schema验证更新操作。
    • [setDefaultsOnInsert] <Object> 如果upsert设置为true,如果创建了新文档,mongoose将应用模型schema中指定的默认值。本选项仅适用于MongoDB >= 2.4,因为其依赖于MongoDB的$setOnInsert操作符
    • [rawResult=false] <Boolean> 设置为true将返回MongoDB驱动的原始值
    • [strict=false] 覆盖此更新的schema的严格模式选项
  • [callback] <Function>

返回

  • <Query>

等同于MongoDB的findAndModify更新命令。

传入callback函数会立即执行,否则返回一个Query对象

示例

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

所有非原子(atomic)操作名称的顶级更新键都被视为set操作:

var query = { name: 'borne' };
Model.findOneAndUpdate(query, { name: 'jason bourne' }, options, callback)

// is sent as
Model.findOneAndUpdate(query, { $set: { name: 'jason bourne' }}, options, callback)


Model.geoSearch()

在Mongoose中调用MongoDB的$geoSearch功能。

参数

  • conditions <Object> 指定条件匹配对象
  • options <Object> 对于$geoSearch来说,有参数(near, maxDistance)必须
    • [lean=false] <Boolean> 设置为true,则返回普通的JavaScript对象,否则返回mongoose文档。参见:Query.lean()
    • near <Array> x,y 指向搜索
    • maxDistance <Number> 距离结果附近点的最大距离
    • limit <Number> 要返回的最大结果数
  • [callback] <Function>

返回

  • <Query>

示例

var options = { near: [10, 10], maxDistance: 5 };
Locations.geoSearch({ type : "house" }, options, function(err, res) {
  console.log(res);
});

本方法不会触发任何中间件。


Model.geoSearch()

在Mongoose中调用MongoDB的$geoSearch功能。

从现有的预先保存在数据库原始数据,创建新文档的快捷方式。返回的文档最初没有标记为已修改的路径。

参数

  • obj <Object>

返回

  • <Model>

示例

// hydrate previous data into a Mongoose document
var mongooseCandy = Candy.hydrate({ _id: '54108337212ffb6d459f854c', type: 'jelly bean' });


Model.init()

模型初始化。

参数

  • [callback] <Function>

除非关闭autoIndex,否则此函数会构建索引

当使用mongoose.model()connection.model()创建模型时,Mongoose会自动调用此函数,因此开发者无需调用它。此函数也是幂等的,因此可以调用它来获取一个promise,做为MyModel.on('index')的替代,并会在索引完成构建后返回resolve状态。

示例

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


Model.insertMany()

批量创建文档

参数

  • doc(s) <Array|Object|*>
  • [options] <Object> 参见:MongoDB驱动选项
    • [ordered=true] <Function> 如果为true,则会在遇到第一个错误时立即失败。如果为false,将在插入所有文档后再报错。ordered = falseinsertMany()称为“无序”insertMany()
    • [rawResult=false] <Boolean> 设置为true将返回MongoDB驱动的原始值,其中的mongoose属性会包含validationErrors(“无序”insertMany())。否则返回mongoose文档。
  • [callback] <Function>

返回

  • <Promise>

验证文档数组并将其插入MongoDB的快捷方式(如果它们全部有效)。此方法比.create()更快,因为它只向服务器发送一个操作,而不是每个文档发送一个。

在将insertMany发送到MongoDB之前,Mongoose会验证每个文档。因此,如果一个文档有验证错误,则不会保存任何文档,除非将ordered选项设置为false

本方法不会触发save中间件,但会触发insertMany()中间件。

示例

var arr = [{ name: 'Star Wars' }, { name: 'The Empire Strikes Back' }];
Movies.insertMany(arr, function(error, docs) {});


Model.listIndexes()

列出MongoDB中当前已定义的索引。

这可能与在schema中定义的索引相同,也可能不同,取决于是否使用autoIndex选项以及是否手动构建索引。

参数

  • [callback] <Function>

返回

  • <Promise|undefined> 指定callback则返回`undefined`,否则返回promise。


Model.mapReduce()

执行mapReduce命令

参数

  • o <Object> 指选map-reduce选项的对象
  • [callback] <Function>

返回

  • <Promise>

o是一个对象,指定所有mapReduce选项以及map和reduce函数。所有选项都会委托给驱动程序实现。有关选项的更多详细信息,请参阅node-mongodb-native mapReduce()文档。

node-mongodb-native的选项外,还支持:

其它选项参数

  • query <Object> 查询筛选对象
  • sort <Object> 输出排序
  • limit <Number> 最大文档数
  • [keeptemp=false] <Boolean> 保留临时数据
  • finalize <Function> finalize 函数
  • scope <Object> 在执行期间暴露给map/reduce/finalize的范围变量
  • [jsMode=false] <Boolean> 使执行保持在JS中。需要MongoDB > 2.0.X
  • [verbose=false] <Boolean> 提供工作执行时间的统计数据
  • readPreference <String>
  • out <Object> 默认{inline:1}, 设置map reduce作业的输出目标
    • {inline:1} 以数组形式返回<结果/li>
    • {replace: 'collectionName'} 将结果添加到collectionName:结果替换集合
    • {reduce: 'collectionName'} 将结果添加到collectionName:如果检测到重复项,则使用 reducer/finalize函数
    • {merge: 'collectionName'} 将结果添加到collectionName:如果存在重复项,则用新文档覆盖旧文档

如果将options.out设置为replacemergereduce,则返回可用于进一步查询的Model实例。针对此模型运行的查询均使用lean选项执行; 这意味着只会返回JavaScript对象,而不应用任何Mongoose魔法(getter,setter等)。

本方法不会触发任何中间件。

示例

var o = {};
// `map()` and `reduce()` are run on the MongoDB server, not Node.js,
// these functions are converted to strings
o.map = function () { emit(this.name, 1) };
o.reduce = function (k, vals) { return vals.length };
User.mapReduce(o, function (err, results) {
  console.log(results)
})
var o = {};
// You can also define `map()` and `reduce()` as strings if your
// linter complains about `emit()` not being defined
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()


Model.populate()

填充文档引用

参数

  • docs <Document|Array> 要填充的单个文档,或多个文档数组
  • options <Object> 用于填充的哈希key/val(path, options)对象
    • [retainNullValues=false] <Boolean> 默认情况下,Mongoose会从填充数组中移除nullundefined。将此项设置为truepopulate()时会在返回数组中包括nullundefined
    • [getters=false] <Boolean> 默认情况下,Mongoose获取localField的原始值。设置为true时,Mongoose会在localField上调用定义的getter
    • path <String> 用于填充的,空格分隔的路径
    • [select] <String> 要选择的字段
    • [match] <String> 查询匹配条件
    • [model] <String> 指定用于填充的模型名,默认情况下从schema中推断
    • [options] <String> query选项,如sortlimit
    • [justOne=false] <Boolean> 如果为true,Mongoose始终将path设置为数组。
  • [callback(err,doc)] <Function>

返回

  • <Promise>

示例

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


Model.prototype.$where

附加到查询的其他属性,调用save()isNewfalse时。


Model.prototype.$where()

创建一个Query并指定$where条件

参数

  • argument <String|Function> JavaScript字符串或匿名函数

返回

  • <Query>

有时需要使用JavaScript表达式在MongoDB中进行查询。这时,可以通过find({ $where: javascript })实现,或者可以通过查询链或使用mongoose快捷方法$where

Blog.$where('this.username.indexOf("val") !== -1').exec(function (err, docs) {});


Model.prototype.base

模型使用的基本Mongoose实例。


Model.prototype.baseModelName

如果当前模型是鉴别器模型,则baseModelName是基本模型的名称。


Model.prototype.collection

模型使用的集合。


Model.prototype.db

模型使用的连接(一个连接可以认为是一个数据库)。


Model.prototype.discriminators

该模型的注册鉴别器。


Model.prototype.increment()

增加当前文档版本号

示例

Model.findById(id, function (err, doc) {
  doc.increment();
  doc.save(function (err) { .. })
})


Model.prototype.model()

返回另一个Model实例

参数

  • name <String> 模型名

示例

var doc = new Tank;
doc.model('User').findById(id, callback);


Model.prototype.modelName

当前模型的名称


Model.prototype.remove()

从数据库中移除当前文档

参数

  • [fn] <function(err|product)> 回调函数

返回

  • <Promise>
product.remove(function (err, product) {
  if (err) return handleError(err);
  Product.findById(product._id, function (err, product) {
    console.log(product) // null
  })
})

作为额外流程控制措施,remove会返回Promise(如果传递了回调则绑定到fn),因此可以链式或挂钩形式来接收错误

product.remove().then(function (product) {
   ...
}).catch(function (err) {
   assert.ok(err)
})


Model.prototype.save()

保存当前文档

参数

返回

  • <Promise|undefined> 传入回调函数则返回undefined,否则返回一个Promise
product.sold = Date.now();
product.save(function (err, product) {
  if (err) ..
})


Model.prototype.schema

当前模型所使用的Schema


Model.prototype.delete

remove的别名


Model.remove()

删除与conditions所匹配的所有文档。要仅删除与conditions匹配的第一个文档,可以设置singletrue

参数

  • conditions <Object>
  • [callback] <Function>

返回

  • <Query>
Character.remove({ name: 'Eddard Stark' }, function (err) {});

此方法会直接MongoDB发送remove命令,不涉及Mongoose文档。因为不涉及Mongoose文档,所以也不执行任何中间件(钩子)。


Model.replaceOne()

update()相同,MongoDB用给定文档替换现有文档(本操作没有像$set这样的原子运算符)。

参数

返回

  • <Query>

本操作会触发replaceOne()中间件


Model.startSession()

参数

  • [options] <Object> 参见:MongoDB驱动选项
    • [causalConsistency=true]] <Boolean> 设置为false则会禁用因果一致性
  • [callback] <Function>

返回

  • <Query>

需要MongoDB >= 3.6.0。启动一个MongoDB会话以使操作保持因果一致性、可重写(Retryable Writes)事务性之类。

调用MyModel.startSession()等同于MyModel.db.startSession()

本操作不会触发任何中间件

示例

const session = await Person.startSession();
let doc = await Person.findOne({ name: 'Ned Stark' }, null, { session });
await doc.remove();
// `doc` will always be null, even if reading from a replica set
// secondary. Without causal consistency, it is possible to
// get a doc back from the below query if the query reads from a
// secondary that is experiencing replication lag.
doc = await Person.findOne({ name: 'Ned Stark' }, null, { session, readPreference: 'secondary' });


Model.syncIndexes()

同步MongoDB与本模型Schema中定义的索引

参数

  • [options] <Object> 传递给ensureIndexes()的选项参数
  • [callback] <Function>

返回

  • <Promise|undefined> 传入回调函数则返回undefined,否则返回一个Promise

本方法将删除_id之外的模型Schema中未定义的所有索引,并构建Schema中存在但MongoDB中不存在的所有索引。

参见博文:What's New in Mongoose 5.2.0: syncIndexes()

示例

const schema = new Schema({ name: { type: String, unique: true } });
const Customer = mongoose.model('Customer', schema);
await Customer.createIndex({ age: 1 }); // Index is not in schema
// Will drop the 'age' index and create an index on `name`
await Customer.syncIndexes();


Model.translateAliases()

转译任何别名字段/条件,以使最终查询或文档对象是纯粹的

参数

  • raw <Object> 可能包含别名键的字段/条件对象

返回

  • <Object> 转译后“纯粹 ”的字段/条件

示例

Character
  .find(Character.translateAliases({
    '名': 'Eddard Stark' // Alias for 'name'
  })
  .exec(function(err, characters) {})

注意:本方法只转译对象类型的参数,其他任何东西都返回原始值


Model.update()

更新数据库中的一个文档但不返回它。

参数

  • conditions <Object>
  • doc <Object>
  • [options] <Object> 参见:Query.prototype.setOptions()
    • [safe=true] <Boolean> 安全模式 (默认为模式中设置的值(true))
    • [upsert=false] <Boolean> 如果文档不存在,则创建文档
    • [multi=false] <Boolean> 是否更新多个文档
    • [runValidators=false] <Boolean> 设置为true,则在此命令上运行更新验证器。更新验证器会根据模型的schema验证更新操作。
    • [setDefaultsOnInsert] <Object> 如果upsert设置为true,如果创建了新文档,mongoose将应用模型schema中指定的默认值。本选项仅适用于MongoDB >= 2.4,因为其依赖于MongoDB的$setOnInsert操作符
    • [strict=false] 覆盖此更新的schema的严格模式选项
    • [overwrite=false] 禁用“仅更新”模式,以使可以覆盖文档
  • [callback(err, rawResponse)] <Function>
    • [err] 发生错误时存在
    • rawResponse MongoDB的完整响应值

返回

  • <Query>

在发送更新命令之前,所有update值都会转换为适当的SchemaTypes。

本方法会触发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);
});

注意:所有非原子(atomic)的操作名称的顶级键更新都会被视为set操作:

var query = { name: 'borne' };
Model.update(query, { name: 'jason bourne' }, options, callback)

// is sent as
Model.update(query, { $set: { name: 'jason bourne' }}, options, callback)
// if overwrite option is false. If overwrite is true, sent without the $set wrapper.

注意:不要将已存在的模型实例用于update子句,因为这不起作用,并且可能引起像无限循环这样的奇怪行为。此外,请确保update子句中没有_id属性,这会导致Mongo返回"Mod on _id not allowed"错误。

在使用更新时会将值转换为适当的类型,但以下内容不适用:

  • defaults
  • setters
  • validators
  • middleware


Model.updateMany()

更新多个符合匹配条件的文档

参数

返回

  • <Query>

本方法与update()功能相同,但MongoDB会更新所有符合条件的文档(而非仅第一个),同时会忽略multi选项。

本方法不触发update()中间件,而是使用pre('updateMany')post('updateMany')代替

本方法会触发updateMany()中间件


Model.updateOne()

更新多个符合匹配条件的文档

参数

返回

  • <Query>

本方法与update()功能相同,但不支持multioverwrite选项参数。

使用本方法应注意:

  • MongoDB将“仅”更新符合匹配条件的第一个文档,而不管multi选项的值如何
  • 如果要覆盖整个文档而不是使用$set等原子运算符,请使用replaceOne()

本方法会触发updateOne()中间件


Model.watch()

参数

返回

  • <ChangeStream> 特定于Mongoose的更改流包装器,继承自EventEmitter

需要MongoDB >= 3.6.0,使用MongoDB更改流监视底层集合的更改。

本方法不会触发任何中间件。

ChangeStream是一个事件发射器,它会发出以下事件:

  • 'change': 发生更改时发出
  • 'error': 发生不可恢复的错误,特别是如果更改流失去与主副本集的连接时,则会有当前错误发出。请关注此GitHub Issue以获取更新。
  • 'end': 如果底层流已关闭,则发出本事件
  • 'close': 如果底层流已关闭,则发出本事件

示例

const doc = await Person.create({ name: 'Ned Stark' });
const changeStream = Person.watch().on('change', change => console.log(change));
// Will print from the above `console.log()`:
// { _id: { _data: ... },
//   operationType: 'delete',
//   ns: { db: 'mydb', coll: 'Person' },
//   documentKey: { _id: 5a51b125c5500f5aa094c7bd } }
await doc.remove();


Model.where()

通过传入的条件,创建一个Query,并返回该Query

参数

  • path <String>
  • [val] <Object> 可选值

返回

  • <Query>

例如,替代写入:

User.find({age: {$gte: 21, $lte: 65}}, callback);

可以改写成:

User.where('age').gte(21).lte(65).exec(callback);

由于Query类还支持where,所以可以继续像下面这样链式使用:

User
.where('age').gte(21).lte(65)
.where('name', /^b/i)
... etc


6. Query


Query()

Query类的构造函数,用于构建查询。

参数

  • [options] <Object>
  • [model] <Object>
  • [conditions] <Object>
  • [collection] <Object> Mongoose的集合

一般不需要直接使用Query()构造函数创建查询实例,而是通过Model中的方法,如Model.find()

示例

const query = MyModel.find(); // `query` is an instance of `Query`
query.setOptions({ lean : true });
query.collection(MyModel.collection);
query.where('age').gte(21).exec(callback);

// You can instantiate a query directly. There is no need to do
// this unless you're an advanced user with a very good reason to.
const query = new mongoose.Query();


Query.prototype.$where()

指定要传递给MongoDBs查询系统的JavasSript函数或表达式。

参数

  • js <String|Function> JavasSript字符串或函数

返回

  • Query

示例

query.$where('this.comments.length === 10 || this.name.length === 5')

// or

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

注意:当你遇到使用其他MongoDB运算符(如$lt)无法满足的条件时,应只使用$where。在使用前一定要阅读所有注意事项


Query.prototype.Symbol.asyncIterator()

返回与 for/await/of循环一起使用的asyncIterator(异步迭代器)。

示例

此函数仅适用于find()查询。一般不需要显式调用此函数,JavaScript运行时将自动调用。

for await (const doc of Model.aggregate([{ $sort: { name: 1 } }])) {
  console.log(doc.name);
}

Node.js v10.x+本身已支持异步迭代器,不需要使用任何标志。在Node.js v8.x中可以使用--harmony_async_iteration标志在应用中启用异步迭代器。

注意:如果Symbol.asyncIterator'undefined',则表示你所使用的Node.js版本不支持异步迭代器。


Query.prototype.all()

指定$all查询条件。

参数

  • [path] <String>
  • val <Number>

使用一个参数调用时,会将最新使用的路径(path)传递给where()


Query.prototype.and()

$and查询条件指定参数。

参数

  • array <Array> 条件列表

返回

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


Query.prototype.batchSize()

指定batchSize选项参数。

参数

  • val <Number> 条件列表

返回

  • Query
query.batchSize(100)

注意:不要在和distinct()一起使用


Query.prototype.box()

指定$box查询条件。

参数

  • val <Object>
  • Upper <[Array]> 右坐标

返回

  • Query
var lowerLeft = [40.73083, -73.99756]
var upperRight= [40.741404,  -73.988135]

query.where('loc').within().box(lowerLeft, upperRight)
query.box({ ll : lowerLeft, ur : upperRight })


Query.prototype.cast()

将此查询转换为model的模式(schema)。

参数

  • [model] <Model>
  • [obj] <Object> 要转换到的的模型。如果未设置,则默认为this.model

返回

  • Object


Query.prototype.catch()

执行返回Promise的查询,该Promise resolve 状态为doc或reject状态为错误。类似.then(),但只接受reject处理程序。

参数

  • [reject] <Function>

返回

  • Promise


Query.prototype.center()

circle的别名,不推荐使用,用circle来代替。


Query.prototype.centerSphere()

指定$centerSphere查询条件。

不推荐使用,用circle来代替。

参数

  • [path] <String>
  • val <Object>

返回

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


Query.prototype.circle()

添加于v3.7.0

指定$circle$centerSphere查询条件。

参数

  • [path] <String>
  • area <Object>

返回

  • Query

示例

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


Query.prototype.collation()

为当前操作添加排序规则。

参数

  • value <Object>

返回

  • Query

需要MongoDB >= 3.4


Query.prototype.comment()

指定comment选项参数

参数

  • val <Number>
query.comment('login query')

注意:不要在和distinct()一起使用


Query.prototype.count()

指定当前查询是一个count查询

参数

  • [filter] <Object> 统计与当前过滤器所匹配的文档数
  • [callback(error, count)] <Function>

返回

  • Query

本方法不推荐使用(弃用),如果要统计文档数可以使用estimatedDocumentCount()countDocuments()方法替代。

本方法会触发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.countDocuments()

指定当前查询是一个countDocuments()查询

本方法类似于count(),但它在传递空过滤器{}时总是进行完整的集合扫描。

参数

  • [filter] <Object> 统计与当前过滤器所匹配的文档数
  • [callback(error, count)] <Function>

返回

  • Query

countDocuments()处理$where几个地理空间运算符的方式也与count()细微差别。

本方法会触发countDocuments()中间件。

示例

const countQuery = model.where({ 'color': 'black' }).countDocuments();

query.countDocuments({ color: 'black' }).count(callback);

query.countDocuments({ color: 'black' }, callback);

query.where('color', 'black').countDocuments(function(err, count) {
  if (err) return handleError(err);
  console.log('there are %d kittens', count);
});

countDocuments()方法类似于count(),但有一些countDocuments()不支持的运算符,以下是count()支持但countDocuments()不支持的运算符及替换建议:


Query.prototype.cursor()

返回一个MongoDB驱动游标的包装。QueryCursor公开Streams3接口以及.next()方法。

参数

  • [options] <Object>
    • [transform] 接受mongoose文档的可选函数。函数的返回值会发出data事件,并由next()返回。

返回

  • QueryCursor

示例

// There are 2 ways to use a cursor. First, as a stream:
Thing.
  find({ name: /^hello/ }).
  cursor().
  on('data', function(doc) { console.log(doc); }).
  on('end', function() { console.log('Done!'); });

// Or you can use `.next()` to manually get the next doc in the stream.
// `.next()` returns a promise, so you can use promises or callbacks.
var cursor = Thing.find({ name: /^hello/ }).cursor();
cursor.next(function(error, doc) {
  console.log(doc);
});

// Because `.next()` returns a promise, you can use co
// to easily iterate through all documents without loading them
// all into memory.
co(function*() {
  const cursor = Thing.find({ name: /^hello/ }).cursor();
  for (let doc = yield cursor.next(); doc != null; doc = yield cursor.next()) {
    console.log(doc);
  }
});


Query.prototype.deleteMany()

声明and/or执行此查询作为deleteMany()操作。

本方法会像remove一样工作,但它会删除与集合中的条件匹配的每个文档,而不管single的值如何。

参数

  • [filter] <Object|Query> MongoDB选择器
  • [callback(error, writeOpResult)] <Function>

返回

  • Query

本方法不会触发任何触发器

Character.deleteMany({ name: /Stark/, age: { $gte: 18 } }, callback)
Character.deleteMany({ name: /Stark/, age: { $gte: 18 } }).then(next)


Query.prototype.deleteOne()

声明and/or执行此查询作为deleteOne()操作。

本方法会像remove一样工作,但它最多会删除一个文档,而不管single的值如何。

参数

  • [filter] <Object|Query> MongoDB选择器
  • [callback(error, writeOpResult)] <Function>

返回

  • Query
Character.deleteOne({ name: 'Eddard Stark' }, callback)
Character.deleteOne({ name: 'Eddard Stark' }).then(next)


Query.prototype.distinct()

声明或执行distinct()操作。

参数

  • [field] <String>
  • [filter] <Object|Query>
  • [callback(error, arr)] <Function>

返回

  • Query

传递callback时会立即执行查询。

本方法不会触发任何触发器

示例

distinct(field, conditions, callback)
distinct(field, conditions)
distinct(field, callback)
distinct(field)
distinct(callback)
distinct()


Query.prototype.elemMatch()

指定$elemMatch查询条件。

参数

  • path <String|Object|Function>
  • criteria <Object|Function>

返回

  • Query

示例

query.elemMatch('comment', { author: 'autobot', votes: {$gte: 5}})

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

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

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


Query.prototype.equals()

指定where()中路径的补充比较值查询条件。

参数

  • val <Object>

返回

  • Query

示例

User.where('age').equals(49);

// is the same as

User.where('age', 49);


Query.prototype.error()

获取/设置此查询的错误标志。

如果此标志不为nullundefined,则exec()promise将会是reject而不执行。

参数

  • [err] <Error|null> 如果设置,exec()将在向MongoDB发送查询之前失败

返回

  • Query

示例

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

请注意,查询转换会在挂钩后运行,因此转换错误将覆盖自定义错误。

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

指定当前查询为estimatedDocumentCount()查询。

在大型集合中查询时,相比countDocuments()更快,因为estimatedDocumentCount()使用集合元数据而不是扫描整个集合。

参数

  • [options] <Object> 直接传递给MongoDB驱动
  • [callback(error, count)] <Function>

返回

  • Query

estimatedDocumentCount()不接受筛选参数,Model.find({ foo: bar }).estimatedDocumentCount()等同于Model.find().estimatedDocumentCount()

本方法会触发estimatedDocumentCount中间件。

示例

await Model.find().estimatedDocumentCount();


Query.prototype.exec()

执行查询。

参数

  • [operation] <String|Function>
  • [callback] <Function> 可选参数,取决于被调用的函数

返回

  • Promise

示例

var promise = query.exec();
var promise = query.exec('update');

query.exec(callback);
query.exec('find', callback);


Query.prototype.exists()

指定$exists条件。

参数

  • [path] <String>
  • val <Number>

返回

  • Query

示例

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

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


Query.prototype.explain()

设置explain选项,这使得此查询返回详细的执行统计信息而不是实际的查询结果。

此方法可用于确定查询使用的索引。

调用query.explain(v)等同于query.setOption({ explain: v })

参数

  • [verbose='queryPlanner'] <String> 详细模式。可选值有:'queryPlanner''executionStats''allPlansExecution'

返回

  • Query

示例

const query = new Query();
const res = await query.find({ a: 1 }).explain('queryPlanner');
console.log(res);


Query.prototype.find()

查找与selectorfilter)所匹配的文档,返回结果是一个文档列表。

如果结果中文档太多,可以使用Query.prototype.cursor(),以合理分配内存。

参数

  • [filter] <Object> MongoDB选择器,不指定则返回全部文档
  • [callback] <Function>

返回

  • Query

示例

// Using async/await
const arr = await Movie.find({ year: { $gte: 1980, $lte: 1989 } });

// Using callbacks
Movie.find({ year: { $gte: 1980, $lte: 1989 } }, function(err, arr) {});


Query.prototype.findOne()

声明一个findOne操作,执行后查找到的第一个文档将会传递到回调函数。

参数

  • [filter] <Object> MongoDB选择器,不指定则返回全部文档
  • [projection] <String> 指定要返回的字段
  • [options] <String> 参见:setOptions()
  • [callback((error, document))] <Function>

返回

  • Query

传入callback时会立即执行查询,结果是查询到的第一个文档。

查询条件filter是可选的,如果传入nullundefined,mongoose会发送一个空的findOne命令到MongoDB,这将返回任意一个文档。

如果想通过文档的_id来查询,可使用Model.findById()代替。

本方法会触发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.findOneAndDelete()

查找一个匹配的文档,删除,并找到的文档(如果有)传到回调函数中。如果传入回调函数会立即执行,否则返回一个Query

参数

  • [conditions] <Object>
  • [options] <Object>
    • [rawResult=false] <Boolean> 如果为true,则返回MongoDB驱动程序的原始结果
    • [strict] <Boolean> 覆盖此更新的schema的严格模式选项
    • [sort] <Object> 排序,匹配多个文档时将按本查询条件来选择文档
    • [maxTimeMS] Number 设置查询时间限制,需要mongodb> = 2.6.0
  • [callback(error, document)] <Function>

返回

  • Query

本方法会生成一个MongoDB findOneAndDelete命令

本方法会触发findOneAndDelete()中间件。

本方法与Model.findOneAndRemove()稍有不同,因为findOneAndRemove()会生成MongoDB findAndModify()命令,而不是findOneAndDelete()。对于大多数Mongoose用例来说,做这种区分是没必要的,更推荐使用findOneAndDelete(),除非有充分的理由不这样做。

示例

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


Query.prototype.findOneAndRemove()

查找一个匹配的文档,删除,并找到的文档(如果有)传到回调函数中。如果传入回调函数会立即执行,否则返回一个Query

参数

  • [conditions] <Object>
  • [options] <Object>
    • [rawResult=false] <Boolean> 如果为true,则返回MongoDB驱动程序的原始结果
    • [strict] <Boolean> :覆盖此更新的schema的严格模式选项
    • [sort] <Object> 排序,匹配到多个文档时将按本查询条件来选择文档
    • [maxTimeMS] Number 设置查询时间限制,需要mongodb> = 2.6.0
  • [callback(error, document)] <Function>

返回

  • Query

本方法会生成一个MongoDB findAndModify命令

本方法会触发findOneAndRemove()中间件。

示例

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


Query.prototype.findOneAndUpdate()

查找匹配的文档,并根据update参数进行更新,可传入任何options所支持的参数,并将找到的文档传入回调函数(如果有)中。如果传递了回调,则立即执行查询。

参数

  • [query] <Object|Query>
  • [update] <Object>
  • [options] <Object>
    • [rawResult=false] <Boolean> 如果为true,则返回MongoDB驱动程序的原始结果
    • [strict] <Boolean> :覆盖此更新的schema的严格模式选项
    • [multipleCastError=false] <Boolean> 默认情况下,强制转换查询时发生的第一个错误mongoose就会返回。启用此选项可聚合所有转换错误后再返回
    • [lean=false] <Boolean> 设置为true,则返回普通的JavaScript对象,否则返回mongoose文档。参见:Query.lean()
    • 设置为true,则返回普通的JavaScript对象,否则返回mongoose文档
    • maxTimeMS Number 设置查询时间限制,需要mongodb> = 2.6.0
    • [new=false] <Boolean> 设置为true将返回修改后的文档,否则返回原始文档(v4.0添加)
    • [upsert=false] <Boolean> 设置为true,如果不存在则创建新对象
    • [fields=false] <Object|String> 要返回的查询字段,等同于.select(fields).findOneAndUpdate()
    • [sort] <Object> 排序,匹配到多个文档时将按本查询条件来选择文档
    • [runValidators=false] <Boolean> 设置为true,则在此命令上运行更新验证器。更新验证器会根据模型的schema验证更新操作。
    • [setDefaultsOnInsert] <Object> 如果upsert设置为true,如果创建了新文档,mongoose将应用模型schema中指定的默认值。本选项仅适用于MongoDB >= 2.4,因为其依赖于MongoDB的$setOnInsert操作符
    • rawResult <Boolean> 如果为true,则返回MongoDB驱动程序的原始结果
    • [context] <String> 如果设置query参数并且开启runValidators,这会runValidators处于打开状态,这将引用更新验证运行的自定义验证器函数中的查询。如果未开启runValidators,则不执行任何操作。
  • [callback(error, document)] <Function>

返回

  • Query

本方法会生成一个MongoDB findAndModify命令

本方法会触发findOneAndUpdate()中间件。

示例

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


Query.prototype.geometry()

指定$geometry查询条件

参数

  • [object] <Object> 必须包含一个String类型的type属性,一个Array类型的coordinates属性是一个

返回

  • Query

示例

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

指定的参数会分配给传递给where()最新路径。

注意:geometry()必须在intersects()within()之后。


Query.prototype.getOptions()

获取查询条件

返回

  • <Object> 查询条件选项

示例

var query = new Query();
query.limit(10);
query.setOptions({ maxTimeMS: 1000 })
query.getOptions(); // { limit: 10, maxTimeMS: 1000 }


Query.prototype.getPopulatedPaths()

获取此查询要填充的路径列表

返回

  • <Array> 表示填充路径的字符串数组

示例

bookSchema.pre('findOne', function() {
   let keys = this.getPopulatedPaths(); // ['author']
 })
 ...
 Book.findOne({}).populate('author')


Query.prototype.getQuery()

以JSON对象的形式返回当前查询条件。

返回

  • <Object> 当前查询条件

示例

var query = new Query();
query.find({ a: 1 }).where('b').gt(2);
query.getQuery(); // { a: 1, b: { $gt: 2 } }


Query.prototype.getUpdate()

以JSON对象的形式返回当前更新操作。

返回

  • <Object> 当前查询条件

示例

var query = new Query();
query.update({}, { $set: { a: 5 } });
query.getUpdate(); // { $set: { a: 5 } }


Query.prototype.gt()

指定$gt查询条件。

参数

  • [path] <String>
  • val <Number>

使用一个参数调用时,将使用传递给where()的最新路径。

示例

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

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


Query.prototype.gte()

指定$gte查询条件。

参数

  • [path] <String>
  • val <Number>

使用一个参数调用时,将使用传递给where()的最新路径。


Query.prototype.hint()

设置查询提示。

参数

  • val <Object> hint 对象

返回

  • <Object> 当前查询条件
query.hint({ indexA: 1, indexB: -1})

注意:本方法不能用于distinct()


Query.prototype.in()

指定$in查询条件。

参数

  • [path] <String>
  • val <Number>

使用一个参数调用时,将使用传递给where()的最新路径。


Query.prototype.intersects()

声明geometry()的交叉查询。

参数

  • [arg] <Object>

返回

  • <Query> 当前查询条件

示例

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

注意:本方法必须在where()之后使用


Query.prototype.j()

请求确认此操作已持久保存到MongoDB的磁盘日志中。

参数

  • val <Boolean>

返回

  • <Query> 当前查询条件

此选项仅对写入数据库的操作有效:

  • deleteOne()
  • deleteMany()
  • findOneAndDelete()
  • findOneAndUpdate()
  • remove()
  • update()
  • updateOne()
  • updateMany()

默认为schema中的writeConcern.j选项

示例

await mongoose.model('Person').deleteOne({ name: 'Ned Stark' }).j(true);


Query.prototype.lean()

设置lean选项

参数

  • [bool=true] <Boolean|Object>

返回

  • <Query> 当前查询条件

从启用了lean选项的查询中返回的文档是纯JavaScript对象,而不是MongooseDocuments。这些对象没有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.limit()

指定查询将返回的最大文档数。

参数

  • val <Number>
query.limit(20)

注意:本方法不能用于distinct()


Query.prototype.lt()

指定$lt查询条件。

参数

  • [path] <String>
  • val <Number>

使用一个参数调用时,将使用传递给where()的最新路径。


Query.prototype.lte()

指定$lte查询条件。

参数

  • [path] <String>
  • val <Number>

使用一个参数调用时,将使用传递给where()的最新路径。


Query.prototype.map()


Query.prototype.maxDistance()

指定$maxDistance查询条件。

参数

  • [path] <String>
  • val <Number>

使用一个参数调用时,将使用传递给where()的最新路径。


Query.prototype.maxScan()

指定maxScan查询条件。

参数

  • val <Number>
query.maxScan(100)

注意:本方法不能用于distinct()


Query.prototype.maxscan()

(弃用)maxScan的别名


Query.prototype.merge()

将另一个Query或condition对象合并到此对象中。

添加于v3.7.0

参数

  • source <Query|Object>

返回

  • <Query> 当前查询条件

传递Query时,将合并查询条件,字段选择和选项。


Query.prototype.mod()

指定$mod查询条件,过滤文件时,其path属性是一个等于除数求模后的余数文档。

参数

  • [path] <String>
  • val <Array> 长度必须是2,第一个元素是divisor(除数),第二个元素是remainder(余数)

返回

  • <Query>

示例

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


Query.prototype.mongooseOptions()

针对此查询的,特定于当前mongoose的选项的 getter/setter。

参数

  • [options] <Object> 指定后将重写当前选项,可选值如下:
    • [populate] <Array> 表示要填充的路径的数组。每次调用Query.prototype.populate()都应该有一个条目
    • [lean=false] <Boolean> 设置为true,则返回普通的JavaScript对象,否则返回mongoose文档。参见:Query.lean()
    • [strict=true] <Boolean> 控制Mongoose如何处理不在schema中进行更新的键。默认情况下,此选项为true,这意味着Mongoose将以静默方式剥离更新中不在架构中的所路径。有关更多信息,请参阅strict模式文档
    • [strictQuery=false] <Boolean> 控制Mongoose如何处理不在查询过滤器(filter)schema 中的键。默认情况下,此选项为false以向后兼容,这意味着即使foo不在schema中,Mongoose也会允许Model.find({foo:'bar'})。有关更多信息,请参阅strictQuery 文档
    • [useFindAndModify=true] <Boolean> 用于解决findAndModify()弃用警告
    • [omitUndefined=false] <Boolean> 在转换更新时删除任何值是undefined的属性。也就是说,如果设置了此项,Mongoose将在将更新发送到服务器之前从Model.updateOne({},{foo:'bar',baz:undefined})中的更新中删除baz
    • [nearSphere] <Boolean> 使用$nearSphere来代替near()。参见Query.prototype.nearSphere()文档

返回

  • <Object> 当前选项

Mongoose在内部选项维护一个单独的对象,因为Mongoose会将Query.prototype.options发送到MongoDB服务器,并且上述选项与MongoDB服务器无关。


Query.prototype.ne()

指定$ne查询条件。

参数

  • val <Number>

使用一个参数调用时,将使用传递给where()的最新路径。


Query.prototype.near()

指定$near$nearSphere查询条件。

参数

  • [path] <String>
  • val <Object>

返回

  • <Query>

这些运算会返回按距离排序的文档。

示例

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


Query.prototype.nearSphere()

指定$nearSphere查询条件。

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

弃用应使用query.near()替代,并将spherical选项设置为true

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


Query.prototype.nin()

指定$nin查询条件。

参数

  • [path] <String>
  • val <Object>

使用一个参数调用时,将使用传递给where()的最新路径。


Query.prototype.nor()

指定$nor查询条件的参数。

参数

  • array <Array> 条件列表

返回

  • <Query>
query.nor([{ color: 'green' }, { status: 'ok' }])


Query.prototype.or()

指定$or查询条件的参数。

参数

  • array <Array> 条件列表

返回

  • <Query>
query.or([{ color: 'red' }, { status: 'emergency' }])


Query.prototype.orFail()

如果没有文档与指定的filter相匹配,则使此查询抛出错误。

这使得与 async/await 集成非常方便,因为orFail()会保存一个额外的if语句来检查是否找不到文档

参数

  • [err] <Function|Error> 如果没有文档与filter相匹配,则抛出可选错误

返回

  • <Query>

示例

// Throws if no doc returned
await Model.findOne({ foo: 'bar' }).orFail();

// Throws if no document was updated
await Model.updateOne({ foo: 'bar' }, { name: 'test' }).orFail();

// Throws "No docs found!" error if no docs match `{ foo: 'bar' }`
await Model.find({ foo: 'bar' }).orFail(new Error('No docs found!'));

// Throws "Not found" error if no document was found
await Model.findOneAndUpdate({ foo: 'bar' }, { name: 'test' }).
  orFail(() => Error('Not found'));


Query.prototype.polygon()

指定$polygon查询条件。

参数

  • [path] <String|Array>
  • [coordinatePairs...] <Array|Object>

返回

  • <Query>

示例

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


Query.prototype.populate()

指定应使用其他文档填充的path

参数

  • path <Object|String> 指定填充路径或所有参数的对象
  • [select] <Object|String> 填充查询的字段选择
  • [model] <Model> 希望用于填充的模型。如果未指定,则populate将通过Schema的ref字段中的名称查找模型。
  • [match] <Object> 填充查询条件。
  • [options] <Object> 填充查询选项设置(如:sort等)

返回

  • <Query>

示例

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

在查询执行并收到响应后填充路径,然后为cpopulation指定的每个路径执行单独的查询。在返回每个查询的响应后,结果将传递给回调。


Query.prototype.read()

确定要从中读取数据的MongoDB节点。

参数

  • pref <String> 列出的首选项或别名之一
  • [tags] <Array> 此查询的可选标记

返回

  • <Query>

pref的可选值

首选项(Preferences):

  • primary 默认,仅从主节读取,如果主要不可用,操作将产生错误。不能与标签结合使用
  • secondary 如果可用则从辅助节点(从节点)读取,否则出错
  • primaryPreferred 从主节点读取(如果可用),否则从辅助节点读取
  • secondaryPreferred 从辅助节点读取(如果可用),否则从主节点读取
  • nearest 所有操作都从最近的候选者中读取,与其他模式不同,此选项将包括随机选择中的所有主、从节点。

别名:

  • 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 }])

更多相关参考:


Query.prototype.readConcern()

设置查询的readConcern选项

参数

  • level <String> 列出的读关注(read concern)级别之一或其别名

返回

  • <Query>

读关注(read concern)级别

读关注:

  • local MongoDB 3.2+ 查询从实例返回,但不保证数据已写入大多数副本集成员(即可以回滚)。
  • available MongoDB 3.6+ 查询从实例返回,但不保证数据已写入大多数副本集成员(即可以回滚)
  • majority MongoDB 3.2+ 该查询返回大多数副本集成员已确认的数据。即使发生故障,读取操作返回的文档也是持久的。
  • linearizable MongoDB 3.4+ 查询返回的数据反映了在读操作开始之前完成的所有成功的多数确认写入。在返回结果之前,查询可以等待并发执行写入以传到大多数副本集成员。
  • snapshot MongoDB 4.0+ 仅适用于多文档事务中的操作。在写入关注“多数”的事务提交时,保证事务操作从多数提交数据的快照中读取。

别名:

  • l-local
  • a-available
  • m-majority
  • lz-linearizable
  • s-snapshot

更多相关参考:


Query.prototype.regex()

指定$regex查询条件。

参数

  • [path] <String>
  • val <String|RegExp>

返回

  • <Query>

使用一个参数调用时,将使用传递给where()的最新路径。


Query.prototype.remove()

声明 and/or 执行此查询作为remove()操作。

参数

  • [filter] <Object|Query> MongoDB选择器
  • [callback(error, writeOpResult)] <Function>

返回

  • <Query>

本操作不会触发任何中间件

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

本操作仅在传递回调时执行。在没有回调时要执行的话,必须先调用remove()然后使用exec()方法来执行。

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

声明 and/or 执行此查询作为replaceOne()操作。

update()操作一样,除了MongoDB将替换现有文档外,还不接受任何原子操作符($set等)

参数

  • [criteria] <Object>
  • [doc] <Object> 更新内容
  • [options] <Object> 可选参数
  • [callback(error, writeOpResult)] <Function>

返回

  • <Query>

replaceOne()不触发update中间件,可使用pre('replaceOne')post('replaceOne')来代替。

本操作会触发replaceOne()中间件


Query.prototype.select()

指定查询中要包含或排除的文档字段(也称为查询“投影”(projection))。

参数

  • arg <Object|String>

返回

  • <Query>

使用字符串语法时,在路径前加上-将标记该路径为排除。当路径没有-前缀时,将会包含在内。如果路径以+为前缀,则会强制包含该路径,这对于在Schema级别排除的路径很有用。

“投影”(projection)投影必须是包含性的或排他性的。也就是说说,必须列出要包括的字段(排除所有其他字段),或列出要排除的字段(这意味着包含所有其他字段)。 _id字段是唯一的例外,因为MongoDB默认包含它

示例

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

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

// Use `+` to override schema-level `select: false` without making the
// projection inclusive.
const schema = new Schema({
  foo: { type: String, select: false },
  bar: String
});
// ...
query.select('+foo'); // Override foo's `select: false` without excluding `bar`

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


Query.prototype.selected()

确定是否已进行字段选择。

返回

  • <Boolean>


Query.prototype.selectedExclusively()

确定是否已进行排他性字段选择。

返回

  • <Boolean>
query.selectedExclusively() // false
query.select('-name')
query.selectedExclusively() // true
query.selectedInclusively() // false


Query.prototype.selectedInclusively()

确定是否已进行包含性字段选择。

返回

  • <Boolean>
query.selectedInclusively() // false
query.select('name')
query.selectedInclusively() // true


Query.prototype.session()

设置与此查询关联的MongoDB会话。会话是将查询标记为事务的一部分的方式。

参数

  • [session] <ClientSession> 来自await conn.startSession()

返回

  • <Query>

调用session(null)将从此查询中删除会话。

const s = await mongoose.startSession();
await mongoose.model('Person').findOne({ name: 'Axl Rose' }).session(s);


Query.prototype.set()

在不更改操作的情况下为此查询的更新添加$set

这对查询中间件很有用,因此无论是否使用updateOne()updateMany()findOneAndUpdate()等,都可以添加更新。

参数

  • path <String|Object> 路径字符串,或键/值对对象
  • [val] <Any> 要设置的值

返回

  • <Query>
// Updates `{ $set: { updatedAt: new Date() } }`
new Query().updateOne({}, {}).set('updatedAt', new Date());
new Query().updateMany({}, {}).set({ updatedAt: new Date() });


Query.prototype.setOptions()

设置查询选项,某些选项仅对某些操作有意义。

参数

  • options <Object>

返回

  • <Query>

选项参数

以下参数公对find()操作有效:

以下参数仅对写操作( update(), updateOne(), updateMany(), replaceOne(), findOneAndUpdate(), findByIdAndUpdate())有效:

  • upsert
  • writeConcern
  • timestamps: 如果timestamps已在schema中设置,将此选项设置为false可跳过该更新的时间戳。 如果schema中选项中未启用timestamps,则无效。

以下参数仅对find(), findOne(), findById(), findOneAndUpdate()findByIdAndUpdate()操作有效:

以下参数对除except update(), updateOne(), updateMany(), remove(), deleteOne()deleteMany()之外的所有操作都有效:

以下参数对所有操作有效:


Query.prototype.setQuery()

将查询条件设置为所提供的JSON对象。

参数

  • new <Object> 将查询条件

返回

  • <undefined>

示例

var query = new Query();
query.find({ a: 1 })
query.setQuery({ a: 2 });
query.getQuery(); // { a: 2 }


Query.prototype.setUpdate()

将当前更新操作设置为新值。

参数

  • new <Object> 更新操作

返回

  • <undefined>

示例

var query = new Query();
query.update({}, { $set: { a: 5 } });
query.setUpdate({ $set: { b: 6 } });
query.getUpdate(); // { $set: { b: 6 } }


Query.prototype.size()

指定$size查询条件。

参数

  • [path] <String>
  • val <Number>

使用一个参数调用时,将使用传递给where()的最新路径。

示例

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

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


Query.prototype.skip()

指定查询要跳过的文档数。

参数

  • val <Number>

示例

query.skip(100).limit(20)

注意:本方法不能用于distinct()


Query.prototype.slaveOk()

弃用设置slaveOk选项。

参数

  • [v=true] <Boolean>

返回

  • <Query>

示例

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


Query.prototype.slice()

指定数组形式的$slice投影。

参数

  • [path] <String>
  • val <Number> 要切片的元素的数量/范围

返回

  • <Query>

示例

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


Query.prototype.snapshot()

指定当前查询为snapshot查询。

返回

  • <Query>

示例

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

注意:本方法不能用于distinct()


Query.prototype.sort()

设置排序顺序。

参数

  • arg <Object|String>
    • 如果传入对象时,值可以是asc, desc, ascending, descending, 1-1
    • 如果传递了字符串,则它必须是以空格分隔的路径名列表。每个路径的排序顺序默认是升序,除非路径名称带有前缀-将被视为降序。

返回

  • <Query>

示例

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

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

注意:本方法不能用于distinct()


Query.prototype.tailable()

设置tailable选项(用于上限集合)。

参数

  • [bool=true] <Boolean>
  • [opts] <Object> 设置选项
    • [numberOfRetries] <Number>
    • [tailableRetryInterval] <Number>

示例

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

注意:本方法不能用于distinct()


Query.prototype.then()

执行返回Promise的查询,该Promise将是包含文档的resolved或包含错误的rejected。

参数

  • [resolve] <Function>
  • [reject] <Function>

返回

  • <Promise>


Query.prototype.toConstructor()

将此查询转换为自定义的可重用Query构造函数,并保留所有参数和选项。

添加于v3.7.3

返回

  • <Query> 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)


Query.prototype.update()

定义 and/or 当前查询为一个update()操作。

参数

  • [criteria] <Object>
  • [doc] <Object> 更新内容/命令
  • [options] <Object>
    • [multipleCastError=false] <Boolean> 默认情况下,强制转换查询时发生的第一个错误mongoose就会返回。启用此选项可聚合所有转换错误后再返回
    • [upsert=false] <Boolean> 设置为truemulti
    • [multi=false] <Boolean> 是否更新多个文档
    • [runValidators=false] <Boolean> 设置为true,则在此命令上运行更新验证器
    • [setDefaultsOnInsert] <Object> 如果upsert设置为true,如果创建了新文档,mongoose将应用模型schema中指定的默认值。本选项仅适用于MongoDB >= 2.4,因为其依赖于MongoDB的$setOnInsert操作符
    • [strict=true] <Boolean> 控制Mongoose如何处理不在schema中进行更新的键。默认情况下,此选项为true,这意味着Mongoose将以静默方式剥离更新中不在架构中的所路径。有关更多信息,请参阅strict模式文档
    • [context] <String> 如果设置query参数并且开启runValidators,这会runValidators处于打开状态,这将引用更新验证运行的自定义验证器函数中的查询。如果未开启runValidators,则不执行任何操作。
    • [read]
    • [writeConcern]
  • [callback(error, writeOpResult)] <Function>

返回

  • <Query>

传递的所有非$atomic操作的路径都将成为$set操作。

本操作会触发update()中间件。

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

// becomes

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

除非传递overwrite选项,否则将空对象{}作为文档传递将导致无操作。如果未设置overwrite选选项,则将忽略更新操作并执行回调,而不会将命令发送到MongoDB,以防止意外覆盖集合中的文档。

注意在传递回调callback时操作会立即执行。在没有回调的情况下会返回一个Query,如果要强制执行,必须首先调用update()然后使用exec()方法执行它。

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

定义 and/or 当前查询为一个updateMany()操作。

update()功能相同,只是MongoDB仅会更新符合criteria的所有文档,而无论multi选项如何。

参数

  • [criteria] <Object>
  • [doc] <Object> 更新内容/命令
  • [options] <Object>
  • [callback(error, writeOpResult)] <Function>

返回

  • <Query>

updateMany不会触发update中间件,触发应使用pre('updateMany')post('updateMany')替代。

本操作会触发updateMany()中间件。


Query.prototype.updateOne()

定义 and/or 当前查询为一个updateOne()操作。

update()功能相同,但不支持multioverwrite选项,且:

  • MongoDB将仅更新匹配criteria的第一个文档,而不管multi选项的值如何。
  • 如果要覆盖整个文档而不是使用$set等原子运算符,请使用replaceOne()

参数

  • [criteria] <Object>
  • [doc] <Object> 更新内容/命令
  • [options] <Object>
  • [callback(error, writeOpResult)] <Function>

返回

  • <Query>

updateOne不会触发update中间件,触发应使用pre('updateOne')post('updateOne')替代。

本操作会触发updateOne()中间件。


Query.prototype.use$geoWithin()

标记选项为不使用$geoWithin

mongoose.Query.use$geoWithin = false;

MongoDB 2.4弃用了$within,而用$geoWithin来替换。Mongoose默认使用$geoWithin(100%向后兼容$within)。如果使用的是旧版MongoDB,请将此标志设置为false,以便使within()查询继续有效。


Query.prototype.w()

设置指定数量的mongod服务器或mongod服务器的标记集,必须在此写入被认为成功之前确认此写入。

参数

  • [val] <String|Number> 0-表示即发即弃;1表示由一台服务器确认;majority表示大多数副本集;或者其它高级选项

返回

  • <Query>

本选项仅对数据库的写操作有效:

  • deleteOne()
  • deleteMany()
  • findOneAndDelete()
  • findOneAndUpdate()
  • remove()
  • update()
  • updateOne()
  • updateMany()

默认为Shema的writeConcern.w选项。

示例

// The 'majority' option means the `deleteOne()` promise won't resolve
// until the `deleteOne()` has propagated to the majority of the replica set
await mongoose.model('Person').
  deleteOne({ name: 'Ned Stark' }).
  w('majority');


Query.prototype.where()

指定用于链式查询的path

参数

  • [path] <String|Objectr>
  • [val] <any>

返回

  • <Query>

示例

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

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

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

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


Query.prototype.within()

为地理空间查询(geo-spatial)指定$within$geoWithin参数。

返回

  • <Query>

示例

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

注意:本方法必须在where()之后调用。

从Mongoose 3.7开始,$geoWithin始终用于查询。若要更改此行为,请参阅Query.prototype.use$geoWithin

在Mongoose 3.7中,within从一个getter变为函数。如果需要使用旧语法,请使用参阅mongoose-within


Query.prototype.wtimeout()

设置w的等待时间。

参数

  • ms <Number> 等待的毫秒数

返回

  • <Query>

如果w>1,则在此操作失败之前等待此写入通过副本集传播的最长时间。默认值为0,表示没有超时。

本选项仅对数据库的写操作有效:

  • deleteOne()
  • deleteMany()
  • findOneAndDelete()
  • findOneAndUpdate()
  • remove()
  • update()
  • updateOne()
  • updateMany()

默认为Schema的writeConcern.wtimeout选项值

示例

// The `deleteOne()` promise won't resolve until this `deleteOne()` has
// propagated to at least `w = 2` members of the replica set. If it takes
// longer than 1 second, this `deleteOne()` will fail.
await mongoose.model('Person').
  deleteOne({ name: 'Ned Stark' }).
  w(2).
  wtimeout(1000);


QueryCursor


QueryCursor()

参数

  • query <Query>
  • options <Object> 传递给.find()的查询选项

QueryCursor是一个并发原语,用于一次处理一个文档的查询结果。QueryCursor实现了Node.js streams3 API,以及一次一个地从MongoDB加载文档的其他几种机制。

QueryCursor执行模型的pre查找钩子,但不执行模型的post查找钩子。

除高级用户外,一般不需要直接调用这个类,而是用Query#cursor来代替


QueryCursor.prototype.addCursorFlag()

添加一个cursor(游标)标志。用于设置noCursorTimeouttailable标志。

参数

  • flag <String>
  • value <Boolean>

返回值

  • <AggregationCursor>


QueryCursor.prototype.close()

将此游标标记为已关闭。

此操作将停止流式传输,后续调用next()将会出错

参数

  • callback <Function>

返回值

  • <Promise>


QueryCursor.prototype.eachAsync()

对游标中的每个文档执行fn。如果fn返回一个promise,将在迭代到下一个之前等待promise解析。

参数

  • fn <Function>
  • [options] <Object>
    • [parallel=1] <Number> 并行执行指定数量的Promise
  • [callback] <Function> 在处理完所有文档后回调

返回值

  • <Promise> 返回完成后解析的promise


QueryCursor.prototype.map()

注册转换函数,随后映射通过流接口或.next()检索的文档。

参数

  • fn <Function>

返回值

  • <QueryCursor>

示例

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


QueryCursor.prototype.next()

从此游标获取下一个文档。没有文档时会返回null

参数

  • callback <Function>

返回值

  • <Promise>


7. Aggregate


Aggregate()

用于构建聚合管道的聚合构造函数。

本类不建议直接使用,而是通过Model.aggregate()构造。

参数

  • [pipeline] <Array> 聚合管道作为对象数组

示例

const aggregate = Model.aggregate([
  { $project: { a: 1, b: 1 } },
  { $skip: 5 }
]);

Model.
  aggregate([{ $match: { age: { $gte: 21 }}}]).
  unwind('tags').
  exec(callback);

使用聚合功能时应该注意以下两点:

  • 返回的文档是普通的Javascript对象,而不是Mongoose文档(因为返回文档的形状不固定)
  • Mongoose没有转换管道阶段。除非_id在数据库中是字符串,否则以下内容无效
new Aggregate([{ $match: { _id: '00000000000000000000000a' } }]);
  // Do this instead to cast to an ObjectId
  new Aggregate([{ $match: { _id: mongoose.Types.ObjectId('00000000000000000000000a') } }]);


Aggregate.prototype.Symbol.asyncIterator()

返回与 for/await/of循环一起使用的、仅适用于find()查询的asyncIterator

不需要显式调用此方法,JavaScript运行时将会自动调用。

示例

for await (const doc of Model.find().sort({ name: 1 })) {
  console.log(doc.name);
}

Node.js v10.x+本身已支持异步迭代器,不需要使用任何标志。在Node.js v8.x中可以使用--harmony_async_iteration标志在应用中启用异步迭代器。

注意:如果Symbol.asyncIterator'undefined',则表示你所使用的Node.js版本不支持异步迭代器。


Aggregate.prototype.addCursorFlag()

设置此聚合上的选项。

此功能将在后续版本中弃用。应使用cursor()collation()等辅助程序来设置各个选项,或直接访问agg.options

参数

  • flag <String>
  • value <Boolean>

返回值

  • <Aggregate>

注意:MongoDB聚合不支持noCursorTimeout标志,如果尝试使用此函数设置该标志,则会出现"unrecognized field 'noCursorTimeout'"错误。


Aggregate.prototype.addFields()

将新的$addFields运算符添加到此聚合管道。

参数

  • arg <Object>

返回值

  • <Aggregate>

需要MongoDB v3.4+

示例

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

为聚合查询设置allowDiskUse选项(2.6.0以下版本忽略)。

参数

  • value <Boolean> 告诉服务器它可以使用硬盘驱动器在聚合期间存储数据。
  • [tags] <Array> 此查询的可选标记

示例

await Model.aggregate([{ $match: { foo: 'bar' } }]).allowDiskUse(true);


Aggregate.prototype.append()

将新运算符追加到此聚合管道。

参数

  • ops <Object> 要追加的运营商

返回值

  • <Aggregate>

示例

aggregate.append({ $project: { field: 1 }}, { $limit: 2 });

// or pass an array
var pipeline = [{ $match: { daw: 'Logic Audio X' }} ];
aggregate.append(pipeline);


Aggregate.prototype.collation()

添加排序规则。

参数

  • collation <Object>

返回值

  • <Aggregate>

示例

Model.aggregate(..).collation({ locale: 'en_US', strength: 1 }).exec();


Aggregate.prototype.count()

将新的$count运算符追加到此聚合管道。

参数

  • field <String> 计数字段的名称

返回值

  • <Aggregate>

示例

aggregate.count("userCount");


Aggregate.prototype.cursor()

为聚合查询设置游标(cursor)选项(忽略<2.6.0)。

参数

  • options <Object>
    • batchSize <Number> 设置游标批量大小
    • [useMongooseAggCursor] <Boolean> 使用实验性的Mongoose特定的聚合游标(用于eachAsync()和其他查询游标语义)

返回值

  • <Aggregate>

请注意下面的不同语法.exec()返回一个游标对象,不需要回调:

var cursor = Model.aggregate(..).cursor({ batchSize: 1000 }).exec();
cursor.each(function(error, doc) {
  // use doc
});


Aggregate.prototype.exec()

在当前绑定的Model上执行聚合管道。

参数

  • [callback] <Function>

返回值

  • <Promise>

示例

aggregate.exec(callback);

// Because a promise is returned, the `callback` is optional.
var promise = aggregate.exec();
promise.then(..);


Aggregate.prototype.explain()

用explain执行聚合。

参数

  • callback <Function>

返回值

  • <Promise>

示例

Model.aggregate(..).explain(callback)


Aggregate.prototype.facet()

组合多个聚合管道。

参数

  • facet <Object>

返回值

  • <Aggregate>

示例

Model.aggregate(...)
 .facet({
   books: [{ groupBy: '$author' }],
   price: [{ $bucketAuto: { groupBy: '$price', buckets: 2 } }]
 })
 .exec();

// Output: { books: [...], price: [{...}, {...}] }


Aggregate.prototype.graphLookup()

将新的自定义$graphLookup运算符追加到此聚合管道,对集合执行递归搜索。

参数

  • options <Object>

返回值

  • <Aggregate>

注意graphLookup最多只能使用100MB内存,即使指定了{allowDiskUse:true},也不允许使用磁盘。

示例

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

将新的自定义$group运算符附加到此聚合管道。

参数

  • arg <Object> $group操作符内容

返回值

  • <Aggregate>
aggregate.group({ _id: "$department" });


Aggregate.prototype.hint()

设置聚合查询的提示选项(忽略<3.6.0)。

参数

  • value <Object|String> 提示对象或索引名称
Model.aggregate(..).hint({ qty: 1, category: 1 } }).exec(callback)


Aggregate.prototype.limit()

向此聚合管道添加新的$limit运算符。

参数

  • num <Number> 要传递到下一阶段的最大记录数
aggregate.limit(10);


Aggregate.prototype.lookup()

将新的自定义$lookup运算符追加到此聚合管道。

参数

  • options <Object> 设置到$lookup,如上面的链接所述

返回值

  • <Aggregate>
aggregate.lookup({ from: 'users', localField: 'userId', foreignField: '_id', as: 'users' });


Aggregate.prototype.match()

将新的自定义$match运算符追加到此聚合管道。

参数

  • arg <Object> $lookup操作符内容

返回值

  • <Aggregate>
aggregate.match({ department: { $in: [ "sales", "engineering" ] } });


Aggregate.prototype.model()

将此聚合绑定到模型。

参数

  • model <Model> 要绑定聚合的模型

返回值

  • <Aggregate>


Aggregate.prototype.near()

将新的自定义$geoNear运算符追加到此聚合管道。

参数

  • arg <Object>

返回值

  • <Aggregate>

注意:必须用作管道中的第一个运算符。

示例

aggregate.near({
  near: [40.724, -73.997],
  distanceField: "dist.calculated", // required
  maxDistance: 0.008,
  query: { type: "public" },
  includeLocs: "dist.location",
  uniqueDocs: true,
  num: 5
});


Aggregate.prototype.option()

可以为中间件或插件设置的任意选项。

参数

返回值

  • <Aggregate>

示例

var agg = Model.aggregate(..).option({ allowDiskUse: true }); // Set the `allowDiskUse` option
agg.options; // `{ allowDiskUse: true }`


Aggregate.prototype.options

传递给aggregate命令的选项。

支持的选项有:


Aggregate.prototype.pipeline()

返回当前管道。

返回值

  • <Array>

示例

MyModel.aggregate().match({ test: 1 }).pipeline(); // [{ $match: { test: 1 } }]


Aggregate.prototype.project()

将新的自定义$project运算符追加到此聚合管道。

还支持Mongoose查询选择语法

参数

  • arg <Object|String>

返回值

  • <Aggregate>

示例

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

置聚合查询的readPreference选项。

参数

  • pref <String> 首选项选项之一或其别名
  • [tags] <Array> 此查询的可选标记

返回值

  • <Aggregate>
Model.aggregate(..).read('primaryPreferred').exec(callback)


Aggregate.prototype.readConcern()

置聚合查询的readConcern级别。

参数

  • level <String> 列出的读取关注级别之一或其别名

返回值

  • <Aggregate>
Model.aggregate(..).readConcern('majority').exec(callback)


Aggregate.prototype.redact()

将新的自定义$redact运算符追加到此聚合管道。

参数

  • expression <Object> redact选项或条件表达式
  • [thenExpr] <String|Object> true状态的条件
  • [elseExpr] <String|Object> false状态的条件

返回值

  • <Aggregate>

如果提供了3个参数,Mongoose将分别用if-then-else的$cond运算符包装它们,如果thenExprelseExpr是string,请确保它以$$开头,如$$DESCEND$$PRUNE$$KEEP

示例

Model.aggregate(...)
 .redact({
   $cond: {
     if: { $eq: [ '$level', 5 ] },
     then: '$$PRUNE',
     else: '$$DESCEND'
   }
 })
 .exec();

// $redact often comes with $cond operator, you can also use the following syntax provided by mongoose
Model.aggregate(...)
 .redact({ $eq: [ '$level', 5 ] }, '$$PRUNE', '$$DESCEND')
 .exec();


Aggregate.prototype.replaceRoot()

将新的自定义$replaceRoot运算符追加到此聚合管道。

参数

  • the <String|Object> 将成为新根文档的字段或文档

返回值

  • <Aggregate>

注意:$replaceRoot运算符要求字段字符串以'$'开头。如果你传入一个字符串,如果指定的字段没有以'$'开头,Mongoose会在前面添加'$'。如果传入对象,则表达式中的字符串不会被更改。

aggregate.replaceRoot("user");

aggregate.replaceRoot({ x: { $concat: ['$this', '$that'] } });


Aggregate.prototype.sample()

将新的自定义$sample运算符追加到此聚合管道。

参数

  • size <Number> 要挑选的随机文件数量

返回值

  • <Aggregate>
aggregate.sample(3); // Add a pipeline that picks 3 random documents


Aggregate.prototype.session()

设置此聚合的会话。

本功能对事务很有用。

参数

  • session <ClientSession>
const session = await Model.startSession();
await Model.aggregate(..).session(session);


Aggregate.prototype.skip()

将新的自定义$skip运算符追加到此聚合管道。

参数

  • num <Number> 下一阶段之前要跳过的记录数

返回值

  • <Aggregate>
aggregate.skip(10);


Aggregate.prototype.sort()

将新的自定义$sort运算符追加到此聚合管道。

参数

  • arg <Object|String>

返回值

  • <Aggregate>

使用本方法时应注意:

  • 如果传入对象时,值可以是asc, desc, ascending, descending, 1-1
  • 如果传递了字符串,则它必须是以空格分隔的路径名列表。每个路径的排序顺序默认是升序,除非路径名称带有前缀-将被视为降序。
// these are equivalent
aggregate.sort({ field: 'asc', test: -1 });
aggregate.sort('field -test');


Aggregate.prototype.sortByCount()

将新的自定义$sortByCount运算符追加到此聚合管道。

参数

  • arg <Object|String> 字符串字段名称或管道对象。

返回值

  • <Aggregate>

注意:$sortByCount运算符要求新的根以'$'开头。如果指定的字段名称不以'$'开头,则Mongoose将前置一个'$'

aggregate.sortByCount('users');
aggregate.sortByCount({ $mergeObjects: [ "$employee", "$business" ] })


Aggregate.prototype.then()

为聚合提供Promise。

参数

  • [resolve] <Function> 成功状态的回调
  • [reject] <Function> 错误状态的回调

返回值

  • <Promise>
Model.aggregate(..).then(successCallback, errorCallback);


Aggregate.prototype.unwind()

将新的自定义$unwind运算符追加到此聚合管道。

参数

  • [fields] <Strong> 要展开的字段

返回值

  • <Aggregate>

注意:$unwind运算符要求新的根以'$'开头。如果指定的字段名称不以'$'开头,则Mongoose将前置一个'$'

aggregate.unwind("tags");
aggregate.unwind("a", "b", "c");


AggregationCursor


AggregationCursor()

参数

  • agg <Aggregate>
  • options <Object>

AggregationCursor是一个并发原语,用于一次处理一个文档的聚合结果。它类似于QueryCursor

AggregationCursorNode.js streams3 API,以及一次一个地从MongoDB加载文档的其他几种机制。

AggregationCursor执行模型的pre聚合钩子,但不执行模型的post聚合钩子。

除非您是高级用户,否则不要直接实例化此类。请改用Aggregate#cursor()


AggregationCursor.prototype.addCursorFlag()

添加一个游标标志。可用于设置noCursorTimeouttailable标志。

参数

  • flag <String>
  • value <Boolean>

返回值

  • <AggregationCursor>


AggregationCursor.prototype.close()

添加一个游标标志。可用于设置noCursorTimeouttailable标志。

参数

  • callback <Function>

返回值

  • <Promise>


AggregationCursor.prototype.eachAsync()

对游标中的每个文档执行fn。如果fn返回一个promise,将在迭代到下一个之前等待promise解析。

参数

  • fn <Function>
  • [options] <Object>
    • [parallel=1] <Number> 并行执行的Pomrise数量
  • [callback] <Function> 所有文档被处理后执行

返回值

  • <Promise>


AggregationCursor.prototype.map()

注册转换函数,随后映射通过流接口或.next()检索的文档。

参数

  • fn <Function>

返回值

  • <AggregationCursor>

示例

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


AggregationCursor.prototype.next()

从此游标获取下一个文档,没有文件时会返回null

参数

  • callback <Function>

返回值

  • <Promise>


8. SchemaType


SchemaType()

SchemaType类的构造函数。

不要直接实例化SchemaType,Mongoose会自动将Schame路径转换为SchemaTypes。

参数

  • path <String>
  • [options] <Object>
  • [instance] <String>

示例

const schema = new Schema({ name: String });
schema.path('name') instanceof SchemaType; // true


SchemaType.prototype.default()

设置当前SchemaType的默认值。

参数

  • val <Function|any> 默认值

返回值

  • <defaultValue>

示例

var schema = new Schema({ n: { type: Number, default: 10 })
var M = db.model('M', schema)
var m = new M;
console.log(m.n) // 10

默认值可以是function,其返回值用于作默认值或字面值本身。无论哪种方式,在创建文档期间设置之前,将根据其Schema类型强制转换该值。

示例

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

添加一个getter到当前SchemaType

参数

  • fn <Function>

返回值

  • <SchemaType>

示例

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)

Getter使原始MongoDB文档值,转换为用户可见的形式。

如,数据库中存储了信用卡号,希望对Mongoose用户隐藏最后4位数之外的所有内容。可以通过以下getter来实现:

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

Getter还可以传递第二个参数,即定义了getter的schematype。这允许基于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.index()

声明此SchemaType的索引选项。

参数

  • options <Object|Boolean|String>

返回值

  • <SchemaType>

示例

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

默认情况下,索引会在后台创建。如果background设置为false,MongoDB将不执行在索引构建之前发送的任何读/写操作。指定background: false会覆盖Mongoose的默认值。


SchemaType.prototype.required()

添加一个required验证器到当前SchemaType。验证器会使用unshift()添加到此SchemaType的验证器数组的前面。

参数

  • required <Boolean|Function|Object> 启用/禁用验证,或返回布尔值或选项对象的函数。当返回对象,其属性如下:
    • [isRequired] <Boolean|Function> 启用/禁用验证,如果是函数应返回布尔值
    • [ErrorConstructor] <Function> 自定义错误构造函数。构造函数接收1个参数,一个包含验证器属性的对象。
  • [message] <String> 自定义错误消息

返回值

  • <SchemaType>

示例

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 >= 18; };
Schema.path('voterRegistrationId').required(isOver18);

required验证程序使用SchemaType的checkRequired函数来确定指定值是否满足验证程序。默认情况下,如果val!= null(即,如果值不为null或undefined),则认为值满足所需的验证器。但是,大多数内置的Mongoose schema类型都会覆盖默认的checkRequired函数。


SchemaType.prototype.select()

设置此路径的默认select()行为,即此路径默认是否包含在查询结果中。

设置为true,则表示此路径应始终包含在结果中;设置为false,则表示默认情况下应将其排除。可以在查询级别覆盖此设置。

参数

  • val <Boolean>

返回值

  • <SchemaType>

示例

xample:
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.set()

为当前schematype添加一个setter。

参数

  • fn <Function>

返回值

  • <SchemaType>

示例

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 with the SchemaType
var s = new Schema({ name: String })
s.path('name').set(capitalize);

Setter允许你在数据到达原始MongoDB文档或查询之前对其进行转换。

如,用户在网站注册时,用户所提供了电子邮箱和密码,并保存到mongodb。我们可能希望将用户的电邮箱标准化为全小写,以避免一个邮箱地址注册多个帐号。这时,就可以通过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'
User.updateOne({ _id: _id }, { $set: { email: 'AVENUE@Q.COM' } }); // update to 'avenue@q.com'

除上述方法法,对于字符串类型的SchemaType还可以通过内置的lowercase: true设置,来实现这一功能:

new Schema({ email: { type: String, lowercase: true }})

Setter还可以传入第二个参数,即定义了setter的schematype。这样可基于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

还可以使用Setter来修改文档上的其他属性。如果要在文档上设置属性name,则Setter会将this作为文档运行。需要注意,在Mongoose 5中,当使用thisname作为query进行查询时,也会运行此Setter。

const nameSchema = new Schema({ name: String, keywords: [String] });
nameSchema.path('name').set(function(v) {
  // Need to check if `this` is a document, because in mongoose 5
  // setters will also run on queries, in which case `this` will be a
  // mongoose query object.
  if (this instanceof Document && v != null) {
    this.keywords = v.split(' ');
  }
  return v;
});


SchemaType.prototype.sparse()

定义一个sparse索引

参数

  • bool <Boolean>

返回值

  • <SchemaType>

示例

var s = new Schema({ name: { type: String, sparse: true })
Schema.path('name').index({ sparse: true });


SchemaType.prototype.text()

定义一个全文索引

参数

  • bool <Boolean>

返回值

  • <SchemaType>

示例

var s = new Schema({name : {type: String, text : true })
 Schema.path('name').index({text : true});


SchemaType.prototype.unique()

定义一个<unique索引

参数

  • bool <Boolean>

返回值

  • <SchemaType>

示例

var s = new Schema({ name: { type: String, unique: true }});
Schema.path('name').index({ unique: true });

注意:如果违反索引约束,在保存时会从MongoDB返回E11000错误,而不是Mongoose验证错误


SchemaType.prototype.validate()

添加验证器到当前文档路径。

参数

  • obj <RegExp|Function|Object> 验证正则表达式,或验证器函数,或哈希对象
    • [validator] <Function> 验证器函数。如果验证器函数返回undefined或真值,则表示验证成功;如果返回假值(undefined除外)或抛出错误,则验证失败。
    • [message] <String|Function> 错误消息。如果是函数,则应返回错误信息字符串。
    • [propsParameter=false] <Boolean> 如果设置为true。Mongoose会将验证器属性对象(包含validator函数,message等)作为第二个参数传递给验证器函数。默认情况下禁用此功能,因为许多验证器依赖于位置参数,启用此功能可能会导致外部验证器出现不可预测的行为。
  • [errorMsg] <String|Function> 错误消息。如果是函数,则应返回错误信息字符串。
  • [type] <String> 验证器类型

返回值

  • <SchemaType>

验证器始终接收要验证的值作为其第一个参数,并且必须返回布尔值。返回false或抛出错误则表示验证失败。

错误消息对象是可选的。如果不传如此参数,则会使用默认错误消息模板

// make sure every value is equal to "something"
function validator (val) {
  return val == 'something';
}
new Schema({ name: { type: String, validate: validator }});

// with a custom error message

var custom = [validator, 'Uh oh, {PATH} does not equal "something".']
new Schema({ name: { type: String, validate: custom }});

// adding many validators at a time

var many = [
    { validator: validator, msg: 'uh oh' }
  , { validator: anotherValidator, msg: 'failed' }
]
new Schema({ name: { type: String, validate: many }});

// or utilizing SchemaType methods directly:

var schema = new Schema({ name: 'string' });
schema.path('name').validate(validator, 'validation of `{PATH}` failed with value `{VALUE}`');

错误消息模板

在上例,生成错误消息时使用了基本的错误消息模板。除了{PATH}{VALUE}之外,还有一些其他模板关键字。

如果Mongoose的内置错误消息模板不够,Mongoose支持将message属性设置为函数。

schema.path('name').validate({
  validator: function() { return v.length > 5; },
  // `errors['name']` will be "name must have length 5, got 'foo'"
  message: function(props) {
    return `${props.path} must have length 5, got '${props.value}'`;
  }
});

要绕过Mongoose的错误消息并只复制验证程序抛出的错误消息,请执行以下操作:

schema.path('name').validate({
  validator: function() { throw new Error('Oops!'); },
  // `errors['name']` will be "Oops!"
  message: function(props) { return props.reason.message; }
});

异步验证

Mongoose支持验证器返回一个promise。返回promise的验证器称为异步验证器。异步验证器会并行运行,validate()将一直等到所有异步验证器执行完成:

schema.path('name').validate({
  validator: function (value) {
    return new Promise(function (resolve, reject) {
      resolve(false); // validation failed
    });
  }
});

异步验证器可用于从数据库中检索其他文档以验证,或有其他 I/O 绑定验证的需求。

验证器的验证发生在pre('save')或手动执行document#validate时。

如果在pre('save')期间验证失败并且没有传递回调来接收错误,则会在Models所关联的数据库连接上发出'error'事件,并传递验证错误对象。


9. VirtualType


VirtualType()

VirtualType类的构造函数

这是Mongoose用于通过Schema.prototype.virtual定义虚拟属性的方法

参数

  • options <Object>
    • [ref] <String|Function> 如果ref不是null,则这将成为填充虚拟字段(populated virtual)
    • [localField] <String|Function> 填充的本地字段,如果这是一个populate virtual。
    • [foreignField] <String|Function> 如果是populate virtual,则填充外部字段。
    • [justOne=false] <Boolean> 默认情况下,populate virtual。设置justOnt后,则填充的虚拟文档会是单个doc或是null
    • [getters=false] <Boolean> 设置为true时,Mongoose会调用你在这个虚拟字段上定义的任何自定义getter。

示例

const fullname = schema.virtual('fullname');
fullname instanceof mongoose.VirtualType // true


VirtualType.prototype._applyDefaultGetters()

如果没有定义getters/getters,则添加一个默认的。

参数

  • fn <Function>

返回值

  • <VirtualType>


VirtualType.prototype.applyGetters()

应用getter到使用可选scopevalue

参数

  • value <Object>
  • scope <Object>

返回值

  • <any> 应用所有getter后的值


VirtualType.prototype.get()

定义一个setter

参数

  • fn <Function>

返回值

  • <VirtualType>
var virtual = schema.virtual('fullname');
virtual.set(function (v) {
  var parts = v.split(' ');
  this.name.first = parts[0];
  this.name.last = parts[1];
});


10. Error


MongooseError.CastError

当Mongoose无法转换值时,将返回此错误类的实例。


MongooseError.DivergentArrayError

如果使用数组投影并以不安全的方式修改数组,则将返回此错误的实例。


MongooseError.DocumentNotFoundError

save()操作失败时将返回此错误类的实例,因为找不到基础文档。构造函数接受一个参数,其为尝试更新文档时Mongoose传递给update()的条件。


MongooseError.MissingSchemaError

当试图访问尚未注册的模型时,会抛出此错误类的实例。


MongooseError.OverwriteModelError

当所使用的连接上已注册具有指定名称的模型时,会抛出此错误类的实例。请参阅有关OverwriteModelError的常见问答


MongooseError.ParallelSaveError

当在同一文档上并行多次调用save()时,将返回此错误类的实例。有关详细信息,请参阅FAQ


MongooseError.ValidationError

验证失败时,将返回此错误类的实例。


MongooseError.ValidatorError

ValidationError中有包含单个ValidatorError实例的错误哈希。


MongooseError.VersionError

在以可能不安全的方式更改数据库中的文档后调用save()时,将返回此错误类的实例。更多相关介绍,请参阅versionKey选项


MongooseError.messages

默认的内置验证器的错误消息。


11. Array


MongooseError.VersionError


MongooseArray.prototype.$pop()

每个文档save()最多一次以原子方式弹出数组。

保存之前在阵列上多次调用此命令会发送与首次调用相同的命令。此更新是使用MongoDB $pop方法实现的,该方法强制实施此限制。

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


MongooseArray.prototype.$shift()

每个文档save()以原子方式移动数组一次。

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


MongooseArray.prototype.addToSet()

如果数组不存在,则向数组添加值。

参数

  • [args...] <any>

返回值

  • <Array> 所添加的值

示例

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]


MongooseArray.prototype.indexOf()

返回obj的索引号,未找到则返回-1

参数

  • obj <Object> 要查找的项目

返回值

  • <Number>


MongooseArray.prototype.inspect()

console.log的helper


MongooseArray.prototype.nonAtomicPush()

以非原子方式将项目推送到数组。

参数

  • [args...] <any>

将整个数组标记为已修改,如果已保存,则将其存储为$set操作,可能会覆盖检索对象与保存对象之间发生的任何更改。


MongooseArray.prototype.pop()

适用于更改跟踪的Array#pop包装

将整个数组标记为已修改,如果已保存,则将其存储为$set操作,可能会覆盖检索对象与保存对象之间发生的任何更改。


MongooseArray.prototype.pull()

原子地从阵列中拉出项目。通过将提供的值转换为嵌入文档,并使用Document.equals()函数进行比较来确定平等性。

参数

  • [args...] <any>

示例

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

要从子文档数组中删除文档,可以传递有_id的匹配对象。

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

也可以直接传递_id并让Mongoose来处理。

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

第一次pull调用会导致数据库上的原子操作,如果反复调用pull而不保存文档,则在整个数组上使用$set操作,同时覆盖数据库上发生的可能更改。


MongooseArray.prototype.push()

适用于更改跟踪的Array#push包装


MongooseArray.prototype.remove()

pull的别名


MongooseArray.prototype.set()

在索引i处设置转换的val并标记修改的数组。

返回值

  • <Array>

示例

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


MongooseArray.prototype.shift()

适用于更改跟踪的Array#shift包装。

示例

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

会将整个数组标记为已修改,如果已保存,则将其存储为$set操作,可能会覆盖检索对象与保存对象之间发生的任何更改。


MongooseArray.prototype.sort()

适用于更改跟踪的Array#sort包装。

会将整个数组标记为已修改,如果已保存,则将其存储为$set操作,可能会覆盖检索对象与保存对象之间发生的任何更改。


MongooseArray.prototype.splice()

适用于更改跟踪和转换的Array#splice包装。

会将整个数组标记为已修改,如果已保存,则将其存储为$set操作,可能会覆盖检索对象与保存对象之间发生的任何更改。


MongooseArray.prototype.toObject()

返回一个原生JavaScript数组

参数

  • options <Object>

返回值

  • <Array>


MongooseArray.prototype.unshift()

适用于更改跟踪的Array#unshift包装。

会将整个数组标记为已修改,如果已保存,则将其存储为$set操作,可能会覆盖检索对象与保存对象之间发生的任何更改。



变更记录

  • [2018-11-16] 基于Mongoose官方文档v5.3.12首次发布