文档
Mongoose documents 表示与存储在 MongoDB 中的文档的一对一映射。 每个文档都是其 模型 的一个实例。
文档与模型
文档 和 模型 是 Mongoose 中不同的类。 Model 类是 Document 类的子类。 当你使用 模型构造函数 时,你会创建一个新文档。
const MyModel = mongoose.model('Test', new Schema({ name: String }));
const doc = new MyModel();
doc instanceof MyModel; // true
doc instanceof mongoose.Model; // true
doc instanceof mongoose.Document; // true
在 Mongoose 中,"document" 通常表示模型的实例。 你不必在不通过模型的情况下创建 Document 类的实例。
检索中
当你使用 findOne()
等模型函数从 MongoDB 加载文档时,你会得到一个 Mongoose 文档。
const doc = await MyModel.findOne();
doc instanceof MyModel; // true
doc instanceof mongoose.Model; // true
doc instanceof mongoose.Document; // true
使用 save()
更新
Mongoose 文档跟踪更改。 你可以使用普通 JavaScript 赋值来修改文档,Mongoose 会将其转换为 MongoDB 更新运算符。
doc.name = 'foo';
// Mongoose sends an `updateOne({ _id: doc._id }, { $set: { name: 'foo' } })`
// to MongoDB.
await doc.save();
save()
方法返回一个 promise。 如果 save()
成功,则 promise 将解析为已保存的文档。
doc.save().then(savedDoc => {
savedDoc === doc; // true
});
如果没有找到对应 _id
的文档,Mongoose 会报一个 DocumentNotFoundError
:
const doc = await MyModel.findOne();
// Delete the document so Mongoose won't be able to save changes
await MyModel.deleteOne({ _id: doc._id });
doc.name = 'foo';
await doc.save(); // Throws DocumentNotFoundError
使用查询更新
save()
函数通常是使用 Mongoose 更新文档的正确方法。 通过 save()
,你可以获得完整的 validation 和 middleware。
对于 save()
不够灵活的情况,Mongoose 允许你通过铸造、middleware 和 有限的验证 创建自己的 MongoDB 更新。
// Update all documents in the `mymodels` collection
await MyModel.updateMany({}, { $set: { name: 'foo' } });
注意 update()
、updateMany()
、findOneAndUpdate()
等 not 执行 save()
中间件。 如果你需要保存中间件和完整验证,请首先查询文档,然后对其进行 save()
。
证实
文档在保存之前经过转换和验证。 Mongoose 首先将值转换为指定类型,然后验证它们。 在内部,Mongoose 在保存之前调用文档的 validate()
方法。
const schema = new Schema({ name: String, age: { type: Number, min: 0 } });
const Person = mongoose.model('Person', schema);
const p = new Person({ name: 'foo', age: 'bar' });
// Cast to Number failed for value "bar" at path "age"
await p.validate();
const p2 = new Person({ name: 'foo', age: -1 });
// Path `age` (-1) is less than minimum allowed value (0).
await p2.validate();
Mongoose 还支持使用 runValidators
选项 对更新进行有限验证。
Mongoose 默认将参数转换为 findOne()
、updateOne()
等查询函数。 但是,Mongoose 默认情况下不会对查询函数参数运行验证。 你需要为 Mongoose 设置 runValidators: true
才能验证。
// Cast to number failed for value "bar" at path "age"
await Person.updateOne({}, { age: 'bar' });
// Path `age` (-1) is less than minimum allowed value (0).
await Person.updateOne({}, { age: -1 }, { runValidators: true });
请阅读 validation 指南了解更多详细信息。
覆盖
有两种不同的方法可以覆盖文档(替换文档中的所有键)。 一种方法是使用 Document#overwrite()
功能,然后使用 save()
。
const doc = await Person.findOne({ _id });
// Sets `name` and unsets all other properties
doc.overwrite({ name: 'Jean-Luc Picard' });
await doc.save();
另一种方法是使用 Model.replaceOne()
。
// Sets `name` and unsets all other properties
await Person.replaceOne({ _id }, { name: 'Jean-Luc Picard' });
下一步
现在我们已经介绍了文档,让我们看一下 子文档。