文档

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(),你可以获得完整的 validationmiddleware

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

下一步

现在我们已经介绍了文档,让我们看一下 子文档