猫鼬引用子文档的不同方式?
mongoose different ways to reference subdocuments?
此语法直接来自有关子类型的 mongoose 文档。但是,我也看到了对子文档的替代引用。有什么区别?
https://mongoosejs.com/docs/subdocs.html
var childSchema = new Schema({ name: 'string' });
var parentSchema = new Schema({
// Array of subdocuments
children: [childSchema],
// Single nested subdocuments. Caveat: single nested subdocs only work
// in mongoose >= 4.2.0
child: childSchema
});
子文档的另一种引用类型
var childSchema = new Schema({ name: 'string' });
mongoose.model('children', childSchema);
var parentSchema = new Schema({
children: {
type: Schema.Types.ObjectId,
ref: 'children'
},
});
以上两种语法完全不同,一种是实际的子文档(children)存储在父文档中,而另一种是新文档存储在children集合中,只有它的引用是存储在父文档中。
案例一:
var childSchema = new Schema({ name: 'string' });
var parentSchema = new Schema({
// Array of subdocuments
children: [childSchema],
// Single nested subdocuments. Caveat: single nested subdocs only work
// in mongoose >= 4.2.0
child: childSchema
});
在这个给定的语法中,父文档也会将子文档存储在父文档中。
父集合中的示例文档如下所示:
{
_id : "parent_random_generated_id"
children :[{ _id : "childid1" , name : "Captain America"},
{ _id : "childid2" , name : "Iron Man"},...],
child : {_id : "childid3" , name : "Thor Odinson"},
...
}
案例二:
var childSchema = new Schema({ name: 'string' });
mongoose.model('children', childSchema);
var parentSchema = new Schema({
children: {
type: Schema.Types.ObjectId,
ref: 'children'
},
});
在这种语法中,子文档将单独存储,它们引用的 id (_id) 将存储在父文档中。
本例中的示例文档如下所示:
// Children documents
{ _id : "childid1" , name : "Captain America"}
{ _id : "childid2" , name : "Iron Man"}
{ _id : "childid3" , name : "Thor Odinson"}
//parent document
{
_id : "parent_random_generated_id"
children :["childid1","childid2",...],
child : "childid3",
...
}
在第二种情况下,您可以使用 Mongodb $lookup
运算符填充子文档,需要时使用 mongodb aggregation pipeline
,或使用 .populate('children')
或 .populate('child')
填充特定的子文档。
我希望这能澄清你的疑问。
区别很简单。 前一个你只是为 child 定义架构 不会为 children 创建一个单独的集合在数据库中,您会将整个 child 文档嵌入到 parent.
并且在 后面的一个中,您通过调用 mongoose.model 为 child 模式定义模型,这会创建一个单独的集合数据库中 children 的 ,然后您可以在 parent 文档中引用 child 文档,而无需将整个 child 文档嵌入 parent 只需添加 child _id.
我已经完成了
案例 2 一些数据写入示例。让我们使用书籍作者场景:
const authorSchema = new Schema({ name: 'string' });
const authorModel = mongoose.model('authors', authorSchema);
const bookSchema = new Schema({
title: String,
author: {
type: Schema.Types.ObjectId,
ref: 'author'
},
});
const bookModel = mongoose.model('books', bookSchema)
const authorData = { name: "John Doe" }
// Check if author does exists. Insert if not or find if yes
const options = {
upsert: true,
new: true,
setDefaultsOnInsert: true
};
const anAuthor = await authorModel.findOneAndUpdate(authorData, authorData, options)
// Insert a new book with reference to `anAuthor`
const aBook = new bookModel({ title: "MyBook" })
aBook.set({ author: anAuthor })
await aBook.save()
在这种语法中,子文档将单独存储,它们引用的 id (_id) 将存储在父文档中。
本例中的示例文档如下所示:
// authors documents
{ _id : "authorId1" , name : "John Doe"}
{ _id : "authorId2" , name : "Iron Man"}
{ _id : "authorId3" , name : "Thor Odinson"}
//books document
{
_id : "parent_random_generated_id"
title: "MyBook",
author : "authorId1",
...
}
对于阅读,您可以使用 populate
:
let result = await bookModel.find()
result = await authorModel.populate(result, { path: 'author' })
此语法直接来自有关子类型的 mongoose 文档。但是,我也看到了对子文档的替代引用。有什么区别?
https://mongoosejs.com/docs/subdocs.html
var childSchema = new Schema({ name: 'string' });
var parentSchema = new Schema({
// Array of subdocuments
children: [childSchema],
// Single nested subdocuments. Caveat: single nested subdocs only work
// in mongoose >= 4.2.0
child: childSchema
});
子文档的另一种引用类型
var childSchema = new Schema({ name: 'string' });
mongoose.model('children', childSchema);
var parentSchema = new Schema({
children: {
type: Schema.Types.ObjectId,
ref: 'children'
},
});
以上两种语法完全不同,一种是实际的子文档(children)存储在父文档中,而另一种是新文档存储在children集合中,只有它的引用是存储在父文档中。
案例一:
var childSchema = new Schema({ name: 'string' });
var parentSchema = new Schema({
// Array of subdocuments
children: [childSchema],
// Single nested subdocuments. Caveat: single nested subdocs only work
// in mongoose >= 4.2.0
child: childSchema
});
在这个给定的语法中,父文档也会将子文档存储在父文档中。
父集合中的示例文档如下所示:
{
_id : "parent_random_generated_id"
children :[{ _id : "childid1" , name : "Captain America"},
{ _id : "childid2" , name : "Iron Man"},...],
child : {_id : "childid3" , name : "Thor Odinson"},
...
}
案例二:
var childSchema = new Schema({ name: 'string' });
mongoose.model('children', childSchema);
var parentSchema = new Schema({
children: {
type: Schema.Types.ObjectId,
ref: 'children'
},
});
在这种语法中,子文档将单独存储,它们引用的 id (_id) 将存储在父文档中。
本例中的示例文档如下所示:
// Children documents
{ _id : "childid1" , name : "Captain America"}
{ _id : "childid2" , name : "Iron Man"}
{ _id : "childid3" , name : "Thor Odinson"}
//parent document
{
_id : "parent_random_generated_id"
children :["childid1","childid2",...],
child : "childid3",
...
}
在第二种情况下,您可以使用 Mongodb $lookup
运算符填充子文档,需要时使用 mongodb aggregation pipeline
,或使用 .populate('children')
或 .populate('child')
填充特定的子文档。
我希望这能澄清你的疑问。
区别很简单。 前一个你只是为 child 定义架构 不会为 children 创建一个单独的集合在数据库中,您会将整个 child 文档嵌入到 parent.
并且在 后面的一个中,您通过调用 mongoose.model 为 child 模式定义模型,这会创建一个单独的集合数据库中 children 的 ,然后您可以在 parent 文档中引用 child 文档,而无需将整个 child 文档嵌入 parent 只需添加 child _id.
我已经完成了
const authorSchema = new Schema({ name: 'string' });
const authorModel = mongoose.model('authors', authorSchema);
const bookSchema = new Schema({
title: String,
author: {
type: Schema.Types.ObjectId,
ref: 'author'
},
});
const bookModel = mongoose.model('books', bookSchema)
const authorData = { name: "John Doe" }
// Check if author does exists. Insert if not or find if yes
const options = {
upsert: true,
new: true,
setDefaultsOnInsert: true
};
const anAuthor = await authorModel.findOneAndUpdate(authorData, authorData, options)
// Insert a new book with reference to `anAuthor`
const aBook = new bookModel({ title: "MyBook" })
aBook.set({ author: anAuthor })
await aBook.save()
在这种语法中,子文档将单独存储,它们引用的 id (_id) 将存储在父文档中。
本例中的示例文档如下所示:
// authors documents
{ _id : "authorId1" , name : "John Doe"}
{ _id : "authorId2" , name : "Iron Man"}
{ _id : "authorId3" , name : "Thor Odinson"}
//books document
{
_id : "parent_random_generated_id"
title: "MyBook",
author : "authorId1",
...
}
对于阅读,您可以使用 populate
:
let result = await bookModel.find()
result = await authorModel.populate(result, { path: 'author' })