Hyl*_*ron 7 javascript mongoose mongodb node.js
我有一个类似的数据结构:
var GrandGrandChild = mongoose.Schema({
attribute: String,
id: Number
});
var GrandChild = mongoose.Schema({
children: [GrandGrandChild],
id: Number,
irrelevantAttribute: String
});
var Child = mongoose.Schema({
children: [GrandChild],
id: Number,
irrelevantAttribute2: String
});
var Parent = mongoose.Schema({
children: [Child],
id: Number,
irrelevantAttribute3: String
});
var GrandParent = mongoose.Schema({
children: [Parent],
id: Number,
irrelevantAttribute4: String
});
Run Code Online (Sandbox Code Playgroud)
这些是包含子文档的很多集合.请注意,ID对于其兄弟姐妹是唯一的,但对于具有相同模式的所有元素而言并非唯一.
因此,一个祖父母可以拥有身份0的父母,另一个祖父母也可以拥有身份0的父母,但是一个祖父母不能拥有2个身份0的父母.
保存的唯一模式是GrandParent模式,而mongoose/mongodb是这个祖父母的所有数据的一个很好的单个大文档.(正是我要找的)
所以这是我的问题:我有一个GrandParent ID,Parent ID,Child ID,GrandChildID和GrandGrandChild ID,我想以某种方式获得所有这些ID所指向的GrandGrandChild对象.
丑陋的方式是,但目前我唯一可以开始工作的方法是创建一个获取GrandParent这个大文档的查询,并手动循环遍历所有数组以找到正确的Parent,然后再循环找到正确的孩子,然后再循环找到合适的孙子,然后再循环,找到我需要的grandgrandchild.
我的问题是,如何在mongoose中编写一个只返回grandgrandchild文档的查询,或者只包含子属性的祖父文档,并且在子类属性中只包含引用的子对象所包含的父对象引用grandgrandchild对象的孙子对象,允许以下结果:
GRANDPARENT PARENT CHILD GRANDCHILD GRANDGRANDCHILD
grandparent.children[0].children[0].children[0].children[0].attribute;
Run Code Online (Sandbox Code Playgroud)
我希望有人可以帮我解决这个问题,我得到的是:
GrandParentModel.findOne(
{
"id" : 0,
"children.id" : 0,
"children.children.id" : 0,
"children.children.children.id" : 0,
"children.children.children.children.id" : 0
},
{"children.children.children.children.$" : 1}, callback);
Run Code Online (Sandbox Code Playgroud)
这个问题的问题在于,不合情理的兄弟姐妹没有被修剪掉.
我希望有人可以帮助我.
Hylke Bron
自从我问这个问题以来已经有一段时间了,但我认为我找到了一种处理此类结构的相当优雅的方式。
在本例中,我将展示它如何仅适用于祖父母、父母和孩子。
我没有在每个文档中存储子文档列表(GrandParent.children、Parent.children),而是创建了以下结构的唯一标识符:
Child.referenceId = {
grandparent: "some key to the grandparent of the parent",
parent: "some key to the parent",
child: "key of this child"
};
Parent.referenceId = {
grandparent: "some key to its grandparent",
parent: "key of this parent"
}
GrandParent.referenceId = {
grandparent: "key of this parent"
}
Run Code Online (Sandbox Code Playgroud)
这将创建祖父母 > 父母 > 孩子的层次结构。
这些模型将类似于以下内容:
var idStructure = {
grandparent: { type: String, required: true },
parent: { type: String, required: false },
child: { type: String, required: false }
};
var GrandParent = mongoose.Schema({
id: idStructure,
irrelevantAttribute: String
});
var Parent = mongoose.Schema({
id: idSructure,
irrelevantAttribute: String
});
var Child = mongoose.Schema({
id: idStructure,
irrelevantAttribute: String
});
Run Code Online (Sandbox Code Playgroud)
请注意,父级并不直接知道其父级,因为它们不存储为子文档。然而,通过referenceId,Parent 和Child 之间仍然存在连接。
当搜索祖父母的整个家谱时,只需执行 3 个查询,然后正确连接它们:
// First find all children which belong to the grandparent
Child.find({"id.grandparent" : "some key to the grandparent"})
.exec(function(err, children)
{
if(err)
return;
Parent.find({"id.grandparent" : "some key to the grandparent"})
.exec(function(err, parents)
{
if(err)
return;
// Loop through the parents and children to connect them before returning to a client
for(var i = 0; i < parents.length; i++)
{
var parent = parents[i];
parent.children = [];
// loop through the children to check if they belong to the current parent
for(var j = 0; j < children.length; j++)
{
var child = children[j];
if(parent.id.parent == child.id.parent)
parent.children.push(child);
}
}
// After filling the children into the parents, get the grandparents and do the same for the parents and grandparents as done for the children and parents.
GrandParent.find({"id.grandparent" : "some key to the grandparent"})
.exec(function(err, grandparents)
{
// TODO: the same as done above (two loops, one loops the grandparents, other loops the parents
// Once this is finished, we have a filled grandparent
});
});
});
Run Code Online (Sandbox Code Playgroud)
上面的代码将导致只有一个祖父母,其中充满了父母,而父母又充满了孩子。
不再找到祖父母的原因是因为祖父母的id应该是唯一的,因为祖父母的referenceId只有一个祖父母属性。
我希望我说清楚了我的观点,因为通过这种方法,人们可以轻松地搜索一个特定的孩子,通过参考 ID 轻松找到其父母,也可以通过参考 ID 轻松找到其祖父母。
这可能有点复杂,但是一旦你自己弄清楚了方法,一切就变得很简单了。
赫尔克
归档时间: |
|
查看次数: |
9114 次 |
最近记录: |