admin管理员组文章数量:1279235
I have a similar datastructure as this:
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
});
These are a lot of collections with subdocuments in them. Note that the ID's are unique to their siblings, but not unique to all elements with that same schema.
So one grand parent can have an parent with id 0, and another grandparent can also have a parent with id 0. but one grandparent can not have 2 parents with id 0.
The only schema that gets saved is the GrandParent schema, and mongoose/mongodb makes a nice big single document of all the data of this grandparent. (Exactly what i am looking for)
So here is my issue: I have a GrandParent ID, Parent ID, Child ID, GrandChildID and GrandGrandChild ID, and i want to somehow get only the GrandGrandChild object to which all these ID's are pointing.
The ugly way would be to, but currently the only way i can get to work, is to make a query that gets this big document of GrandParent, and manually loop through all arrays to find the right Parent, then loop again to find the right child, then loop again to find the right grandchild, then loop again and find the grandgrandchild im needing here.
My question is, how would i pose a query in mongoose that either returns only the grandgrandchild document, or the grandparent document with only the children attribute included, and in that children attribute only the parent object included that refers to the child object that refers to the grandchild object that refers to the grandgrandchild object, allowing the following with the result:
GRANDPARENT PARENT CHILD GRANDCHILD GRANDGRANDCHILD
grandparent.children[0].children[0].children[0].children[0].attribute;
I hope someone can help me on this query, as far is i got is this:
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);
The problem with this query is that the unnessicary siblings arent trimmed away.
I hope someone can help me out.
Hylke Bron
I have a similar datastructure as this:
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
});
These are a lot of collections with subdocuments in them. Note that the ID's are unique to their siblings, but not unique to all elements with that same schema.
So one grand parent can have an parent with id 0, and another grandparent can also have a parent with id 0. but one grandparent can not have 2 parents with id 0.
The only schema that gets saved is the GrandParent schema, and mongoose/mongodb makes a nice big single document of all the data of this grandparent. (Exactly what i am looking for)
So here is my issue: I have a GrandParent ID, Parent ID, Child ID, GrandChildID and GrandGrandChild ID, and i want to somehow get only the GrandGrandChild object to which all these ID's are pointing.
The ugly way would be to, but currently the only way i can get to work, is to make a query that gets this big document of GrandParent, and manually loop through all arrays to find the right Parent, then loop again to find the right child, then loop again to find the right grandchild, then loop again and find the grandgrandchild im needing here.
My question is, how would i pose a query in mongoose that either returns only the grandgrandchild document, or the grandparent document with only the children attribute included, and in that children attribute only the parent object included that refers to the child object that refers to the grandchild object that refers to the grandgrandchild object, allowing the following with the result:
GRANDPARENT PARENT CHILD GRANDCHILD GRANDGRANDCHILD
grandparent.children[0].children[0].children[0].children[0].attribute;
I hope someone can help me on this query, as far is i got is this:
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);
The problem with this query is that the unnessicary siblings arent trimmed away.
I hope someone can help me out.
Hylke Bron
Share Improve this question asked Apr 23, 2013 at 9:56 HylkeHylke 7051 gold badge6 silver badges18 bronze badges3 Answers
Reset to default 3it has been some time since I asked this question, but I think I found a rather elegant way of working with these kind of structures.
In this case I'll show how it works with only GrandParent, Parent and Child.
Instead of storing a list of subdocuments in each document (GrandParent.children, Parent.children), I created an unique identifier of the following structure:
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"
}
This creates a hierarchy of GrandParent > Parent > Child.
The models would be something like the following:
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
});
Notice that a Parent doesnt directly knows its parent, for they are not stored as subdocuments. Yet there still is a connection between Parent and Child, through the referenceId.
When searching for the whole familytree of a GrandParent, one would simply execute 3 queries, and then connect them correctly:
// 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
});
});
});
The code above would result in just ONE grandparent, filled with parents, which are filled with children.
The reason no more grandparents would be found is because the id of the grandParent should be unique, for the referenceId of the grandparent only has a grandparent property.
I hope i made my point clear, because through this method, one can easily search for one specific child, easily get its parent through the reference id, and its grandparent also through the reference id.
It might be a bit plex, but once you figure the method out for yourself, its all kinda straight forward.
Hylke
Is very difficult to get this kind of things work in a clean way.
I didn't find a clean solution on this topic, but maybe I can help you with the looping thing. You can avoid the loop using: var doc = parent.children.id(id); Finding a sub-document
I hope this help you. Regards, Sebastian.
this worked for me
model.find({_id:args.id},{ mentList: { $elemMatch: { _id: todo.mentList[todo.mentList.length-1] } } },(err, todos) => {
if (err) reject(err)
else resolve(todos)
console.log(todos);
})
$elemMatch (projection)
本文标签: javascriptUse mongoose query to get only a subdocumentStack Overflow
版权声明:本文标题:javascript - Use mongoose query to get only a subdocument - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741218431a2360499.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论