英文:
How to refer to a sub collection from another collection in MongoDB/Mongoose?
问题
在这个集合中,是否有一种方式可以定义一个字段,用来引用子文档,以创建引用特定子文档的记录?或者我应该只使用一个字符串字段,并将子文档的ID存储在其中?
希望在Report集合中的记录中得到类似以下的结果:
{
"_id" : ObjectId("63bc482afde665158cd71a41"),
"createdBy" : ObjectId("63b9d635e6225fa0ff29f316"),
"parent" : ObjectId("63bbac19fde665158cd718e9"),
"child" : ObjectId("63ba83eef2f128e2f8e69140"),
// 其他属性
}
英文:
I have a collection in mongo, let's call it Parent, with a property called children, something like this
const ParentSchema = mongoose.Schema({
children: [{
//children properties
}],
//other collection properties
When I save a record in this collection, every child gets an objectId like this
"_id" : ObjectId("63ba8421f2f128e2f8e6916d")
Then I have a collection called Report. In this collection I can refer to Parent like this
const ReportSchema = mongoose.Schema({
parent: {
type: mongoose.Schema.Types.ObjectId,
ref: "Parent",
required: false
},
is there a way to define in this collection a field that refers to children, in order to create a record referring to a specific child? Or should I just use a string field and store the child id in there?
The idea would be to endup with records in Report like
{
"_id" : ObjectId("63bc482afde665158cd71a41"),
"createdBy" : ObjectId("63b9d635e6225fa0ff29f316"),
"parent" : ObjectId("63bbac19fde665158cd718e9"),
"child" : ObjectId("63ba83eef2f128e2f8e69140"),
// other properties
}
答案1
得分: 1
Mongoose的ref
属性对此无效,因为它接受一个模型名称、模型或返回模型名称或模型的函数,但您没有对子文档进行建模(这样做会暗示将它们存储在单独的集合中,而不是作为父文档上的数组)。
您仍然可以拥有一个childId
字段,其类型为ObjectId
,并将子文档的ID放在那里(您说是字符串,但ObjectId
更合适),而不将其声明为ref
,即
const ReportSchema = mongoose.Schema({
parent: {
type: mongoose.Schema.Types.ObjectId,
ref: "Parent",
required: false
},
child: mongoose.Schema.Types.ObjectId,
}
但是,您将无法使用populate()
来填充child
字段,因为mongoose的填充功能要求存在单独的Child模型/集合。
当然,您可以填充父字段,然后编写代码来从填充的父文档的children
数组中提取子文档。您还可以编写自定义聚合管道,在数据库端执行此操作。
但您最好的选择可能是坚持不懈地创建一个ChildSchema
,一个Child
模型,在Parent
的children
数组中使用它作为ref
,然后您还可以在ReportSchema
中的child
字段中使用它作为ref
,这样mongoose的填充功能将适用于它。
英文:
Mongoose's ref
property won't work for this, since it takes a model name, a Model, or a function that returns a model name or model but you aren't modeling children (doing so would imply storing them in a separate collection, not as an array on parent documents).
You can still just have a childId
field of ObjectId
type and put the child's ID there (you said string, but ObjectId
is more appropriate) without declaring it as a ref
, i.e.
const ReportSchema = mongoose.Schema({
parent: {
type: mongoose.Schema.Types.ObjectId,
ref: "Parent",
required: false
},
child: mongoose.Schema.Types.ObjectId,
}
However you wouldn't be able to populate()
the child
field since mongoose's populate features would require there to be a separate Child model/collection.
You would of course be able to populate the parent field, then write code to pull the child document out of the populated parent's children
array. You could also write a custom aggregation pipeline to do this on the DB side of the wire.
But your best best may be to bite the bullet and make a ChildSchema
, a Child
model, use that as a ref
in Parent
's children
array, and then you can also use it as a ref
for a child
field in ReportSchema
and mongoose's population features will work for it.
答案2
得分: -1
"为了良好的实践,我更喜欢在报告模式中添加 ParentId,而不需要将所有子项的ID存储在父项中。如果数据量大,可能会导致问题。
const ParentSchema = mongoose.Schema({
//其他集合属性
})
const ReportSchema = mongoose.Schema({
parent: {
type: mongoose.Schema.Types.ObjectId,
ref: "Parent",
required: true
},
//其他键
})
"
英文:
For good practice, I'll prefer add ParentId in the Report Schema no need to store the all child id in the parents
if data will be large it may create issue..
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const ParentSchema = mongoose.Schema({
//other collection properties
})
<!-- end snippet -->
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const ReportSchema = mongoose.Schema({
parent: {
type: mongoose.Schema.Types.ObjectId,
ref: "Parent",
required: true
},
// other keys
})
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论