在 Mongoose 中,嵌套文档是指将多个文档组合成一个文档,其中一个文档是父文档,其他文档是子文档。在操作嵌套文档时,需要注意一些细节和技巧,下面将详细介绍。
1. 嵌套文档的定义
在 Mongoose 中,嵌套文档的定义是通过 Schema 和 Model 完成的。Schema 是用于定义文档的结构,而 Model 是定义了一个文档对象,并对其进行操作。在 Schema 中,通过一个对象的嵌套来定义文档的嵌套结构。
const SubSchema = new mongoose.Schema({ name: String, age: Number }); const ParentSchema = new mongoose.Schema({ title: String, sub: SubSchema });
在上面的例子中,ParentSchema
定义了一个包含 title
字段和 sub
字段的文档,sub
字段是一个子文档,它包含了 name
和 age
字段。
2. 嵌套文档的创建
在创建嵌套文档时,需要首先创建父文档,然后再往其子文档的路径上添加文档数据。可以通过以下方式创建和保存嵌套文档:
-- -------------------- ---- ------- -- ----- ----- ------ - --- ------------- ------ ------- ------- ---- -- --- -- ------- --------------- - ---- ------ -------------- - --- -- ---- --------------
在上面的例子中,首先创建了 ParentModel
的实例 parent
,然后往其子文档 sub
的路径上添加了文档数据,最后保存文档。需要注意的是,当你创建子文档时,需要保证其父文档已经创建并保存成功,否则会导致子文档数据无法被保存。
3. 嵌套文档的读取
在读取嵌套文档时,只需要通过 dot notation
(点符号)来访问嵌套文档的属性即可,点符号表示文档之间的嵌套关系。下面是一个读取嵌套文档的例子:
ParentModel.findOne({title: 'Parent title'}) .exec((err, parent) => { console.log(parent.sub.name); // 'Sub name' console.log(parent.sub.age); // 20 });
在上面的例子中,通过 findOne()
方法找到了 title
字段等于 'Parent title'
的文档,然后通过点符号访问 sub
文档的属性。
4. 嵌套文档的更新
在更新嵌套文档时,需要使用 $set
操作符。下面是一个更新嵌套文档的例子:
ParentModel.findOne({title: 'Parent title'}) .exec((err, parent) => { parent.sub = { name: 'New sub name', age: 30 }; parent.save(); });
在上面的例子中,首先通过 findOne()
方法找到了 title
字段等于 'Parent title'
的文档,然后把其 sub
字段赋值为一个新的子文档,最后保存文档。
需要注意的是,如果只是更新子文档的某个属性,而不是整个子文档,可以使用以下方式:
ParentModel.findOne({title: 'Parent title'}) .exec((err, parent) => { parent.sub.name = 'New name'; parent.markModified('sub'); parent.save(); });
在上面的例子中,通过 markModified()
方法标记了 sub
字段已被修改过,然后再调用 save()
方法保存文档。
5. 嵌套文档的删除
在删除嵌套文档时,需要使用 $unset
操作符,把子文档的属性置为 null
。下面是一个删除嵌套文档的例子:
ParentModel.findOne({title: 'Parent title'}) .exec((err, parent) => { parent.sub = null; parent.save(); });
在上面的例子中,把 parent
文档的 sub
字段置为 null
即可删除子文档。
总结
本文介绍了在 Mongoose 中如何对嵌套文档进行操作。需要注意的是,在创建、更新、删除嵌套文档时,需要分别使用不同的操作符和方法。掌握这些操作的技巧和细节,可以更加熟练地开发 Mongoose 应用程序。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/647028b9968c7c53b0e4bf4f