Reputation: 1845
Let's say you have two collections: CollectionA and CollectionB.
In CollectionA you have a document model like this
_id
childs{
kind
position
childA
childB
}
With childA
being a reference to a document in the CollectionA, and childB
being a reference to a document in CollectionB
In CollectionB you have a document model like this
_id
propertyA
propertyB
What I've done in Node.Js is a recursive function like in this pseudocode
function getProperties(id){
let properties = [];
if(id) {
let document = collectionB.findOne(id);
if(document && document.childs) {
for(let child of document.childs) {
if(child.childB){
properties = properties.concat(getProperties(child.childB)):
}
if(child.childA){
let documentA = collectionA.findOne(child.childA);
if(documentA){
properties.push(documentA.prpertyA);
}
}
}
}
}
return properties;
}
However, as childs grows, the time to get all the properties from the hierarchy grows as well, sometimes leading to a minute of waiting time (or even timeouts in some cases!). So, how can I improve this, maybe using some mongodb native functions? I'm already using DataLoader inside the findOne
functions, which helped but not as much as I thought.
Upvotes: 0
Views: 301
Reputation: 466
You can use aggregate to create complex queries in a simple way.
For your example, you have two collections: Collection A, Collection B
Your base collection is B, so we can create an aggregate pipeline from collection B
db.collectionB.aggregate([
{
$match: { _id: id } //
},
{
$lookup:
{
from: 'collectionB',
localField: '_id',
foreignField: 'childB',
as: 'childBobj'
}
}
{
$lookup:
{
from: 'collectionA',
localField: '_id',
foreignField: 'childA',
as: 'childAobj'
}
}
])
The query is not completely satisify your goal, Please make changes accordingly.
And I highly reccommended you to take a look at db.collection.aggregate
And even you can use indexing to make this query execution time faster.
Happy coding!.
Upvotes: 1