0

假设您有两个集合:CollectionA 和 CollectionB。

在 CollectionA 中,您有一个像这样的文档模型

_id
childs{
   kind
   position
   childA
   childB
}

childA引用 CollectionA 中的文档,并引用childBCollectionB 中的文档

在 CollectionB 你有一个像这样的文档模型

_id
propertyA
propertyB

我在 Node.Js 中所做的是一个递归函数,就像在这个伪代码中一样

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;
}

然而,随着孩子的成长,从层次结构中获取所有属性的时间也会增加,有时会导致一分钟的等待时间(在某些情况下甚至会超时!)。那么,我该如何改进这一点,也许使用一些 mongodb 原生函数?我已经在findOne函数中使用了 DataLoader,这有帮助,但没有我想象的那么大。

4

1 回答 1

1

您可以使用聚合以简单的方式创建复杂的查询。

对于您的示例,您有两个集合: Collection ACollection B

您的基础集合是 B,因此我们可以从集合 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'
    }
}
])

查询未完全满足您的目标,请进行相应更改。

我强烈建议你看看db.collection.aggregate

甚至您也可以使用索引来缩短此查询的执行时间。

快乐编码!

于 2019-12-20T16:04:50.193 回答