Models模型

Models are fancy constructors compiled from Schema definitions. 模型是从Schema定义编译而来的奇特构造函数。An instance of a model is called a document. 模型的实例称为文档Models are responsible for creating and reading documents from the underlying MongoDB database.模型负责从底层MongoDB数据库中创建和读取文档。

Compiling your first model编译您的第一个模型

When you call mongoose.model() on a schema, Mongoose compiles a model for you.当您在一个模式上调用mongoose.model()时,Mongoose会为您编译一个模型。

const schema = new mongoose.Schema({ name: String, size: String });
const Tank = mongoose.model('Tank', schema);

The first argument is the singular name of the collection your model is for. 第一个参数是您的模型所针对的集合的单数名称。Mongoose automatically looks for the plural, lowercased version of your model name.Mongoose会自动查找模型名称的复数、小写版本。 Thus, for the example above, the model Tank is for the tanks collection in the database.因此,对于上面的示例,模型Tank用于数据库中的Tank集合。

Note: The .model() function makes a copy of schema. .model()函数的作用是复制模式。Make sure that you've added everything you want to schema, including hooks, before calling .model()!在调用.model()之前,请确保您已经添加了想要schema的所有内容,包括钩子!

Constructing Documents构造文档

An instance of a model is called a document. Creating them and saving to the database is easy.模型的实例称为文档。创建它们并保存到数据库很容易。

const Tank = mongoose.model('Tank', yourSchema);

const small = new Tank({ size: 'small' });
small.save(function(err) {
if (err) return handleError(err);
// saved!保存成功!
});

// or

Tank.create({ size: 'small' }, function(err, small) {
if (err) return handleError(err);
// saved!保存成功!
});

// or, for inserting large batches of documents或者,用于插入大批量文档
Tank.insertMany([{ size: 'small' }], function(err) {

});

Note that no tanks will be created/removed until the connection your model uses is open. 请注意,在打开模型使用的连接之前,不会创建/删除储罐。Every model has an associated connection. 每个模型都有关联的连接。When you use mongoose.model(), your model will use the default mongoose connection.当您使用mongoose.model()时,您的模型将使用默认的mongoose连接。

mongoose.connect('mongodb://127.0.0.1/gettingstarted');

If you create a custom connection, use that connection's model() function instead.如果您创建了一个自定义连接,请改用该连接的model()函数。

const connection = mongoose.createConnection('mongodb://127.0.0.1:27017/test');
const Tank = connection.model('Tank', yourSchema);

Querying查询

Finding documents is easy with Mongoose, which supports the rich query syntax of MongoDB. 使用Mongoose查找文档很容易,它支持MongoDB丰富的查询语法。Documents can be retrieved using a model's find, findById, findOne, or where static functions.可以使用modelfindfindByIdfindOnewhere静态函数来检索文档。

Tank.find({ size: 'small' }).where('createdDate').gt(oneYearAgo).exec(callback);

See the chapter on queries for more details on how to use the Query api.有关如何使用Query api的更多详细信息,请参阅查询章节。

Deleting删除

Models have static deleteOne() and deleteMany() functions for removing all documents matching the given filter.模型具有静态deleteOne()deleteMany()函数,用于删除与给定filter匹配的所有文档。

Tank.deleteOne({ size: 'large' }, function(err) {
if (err) return handleError(err);
// deleted at most one tank document最多删除一个储罐文件
});

Updating更新

Each model has its own update method for modifying documents in the database without returning them to your application. 每个model都有自己的update方法,用于修改数据库中的文档而不将其返回到应用程序。See the API docs for more detail.有关更多详细信息,请参阅Model API文档。

Tank.updateOne({ size: 'large' }, { name: 'T-90' }, function(err, res) {
// Updated at most one doc, `res.nModified` contains the number of docs that MongoDB updated最多更新一个文档,`res.nModified`包含MongoDB更新的文档数量
});

If you want to update a single document in the db and return it to your application, use findOneAndUpdate instead.如果要更新数据库中的单个文档并将其返回到应用程序,请改用findOneAndUpdate

Change Streams更改流

Change streams更改流 provide a way for you to listen to all inserts and updates going through your MongoDB database. 为您提供一种方法来监听MongoDB数据库中的所有插入和更新。Note that change streams do not work unless you're connected to a MongoDB replica set.请注意,除非您连接到MongoDB副本集,否则更改流是不起作用的。

async function run() {
// Create a new mongoose model创建一个新的猫鼬模型
const personSchema = new mongoose.Schema({
name: String
});
const Person = mongoose.model('Person', personSchema);

// Create a change stream. The 'change' event gets emitted when there's a change in the database创建变更流。当数据库发生更改时,会发出“change”事件
Person.watch().
on('change', data => console.log(new Date(), data));

// Insert a doc, will trigger the change stream handler above插入一个文档,将触发上面的变更流处理程序
console.log(new Date(), 'Inserting doc');
await Person.create({ name: 'Axl Rose' });
}

The output from the above async function will look like what you see below.上面async函数的输出将与您在下面看到的内容类似。

2018-05-11T15:05:35.467Z 'Inserting doc'
2018-05-11T15:05:35.487Z 'Inserted doc'
2018-05-11T15:05:35.491Z { _id: { _data: ... },
operationType: 'insert',
fullDocument: { _id: 5af5b13fe526027666c6bf83, name: 'Axl Rose', __v: 0 },
ns: { db: 'test', coll: 'Person' },
documentKey: { _id: 5af5b13fe526027666c6bf83 } }

You can read more about change streams in mongoose in this blog post.你可以在这篇博客文章中阅读更多关于mongoose中变更流的内容。

Views视图

MongoDB Views视图 are essentially read-only collections that contain data computed from other collections using aggregations. 本质上是只读集合,包含使用聚合从其他集合计算的数据。In Mongoose, you should define a separate Model for each of your Views. You can also create a View using createCollection().在Mongoose中,您应该为每个视图定义一个单独的模型。您也可以使用createCollection()创建视图。

The following example shows how you can create a new RedactedUser View on a User Model that hides potentially sensitive information, like name and email.以下示例显示了如何在隐藏潜在敏感信息(如姓名和电子邮件)的User模型上创建新的RedactedUser视图。

// Make sure to disable `autoCreate` and `autoIndex` for Views,请确保禁用视图的`autoCreate`和`autoIndex`,
// because you want to create the collection manually.因为您要手动创建集合。
const userSchema = new Schema({
name: String,
email: String,
roles: [String]
}, { autoCreate: false, autoIndex: false });
const User = mongoose.model('User', userSchema);

const RedactedUser = mongoose.model('RedactedUser', userSchema);

// First, create the User model's underlying collection...首先,创建用户模型的基础集合……
await User.createCollection();
// Then create the `RedactedUser` model's underlying collection as a View.然后将`RedactedUser`模型的基础集合创建为视图
await RedactedUser.createCollection({
viewOn: 'users', // Set `viewOn` to the collection name, **not** model name.
pipeline: [
{
$set: {
name: { $concat: [{ $substr: ['$name', 0, 3] }, '...'] },
email: { $concat: [{ $substr: ['$email', 0, 3] }, '...'] }
}
}
]
});

await User.create([
{ name: 'John Smith', email: 'john.smith@gmail.com', roles: ['user'] },
{ name: 'Bill James', email: 'bill@acme.co', roles: ['user', 'admin'] }
]);

// [{ _id: ..., name: 'Bil...', email: 'bil...', roles: ['user', 'admin'] }]
console.log(await RedactedUser.find({ roles: 'admin' }));

Note that Mongoose does not currently enforce that Views are read-only. 请注意,Mongoose目前并没有强制要求视图是只读的。If you attempt to save() a document from a View, you will get an error from the MongoDB server.如果您试图从视图save()文档,您将从MongoDB服务器收到一个错误。

Yet more还有更多

The API docs cover many additional methods available like count, mapReduce, aggregate, and more.API文档涵盖了许多其他可用方法,如countmapReduceaggregate等。

Next Up下一步

Now that we've covered Models, let's take a look at Documents.现在我们已经介绍了Models,让我们来看一下文档