Mongo - 选择具有最大子文档数量的父文档,速度更快?

时间:2014-11-17 12:26:07

标签: mongodb query-optimization

我对mongo很陌生,并试图在查询后继续工作。并且工作正常,但它需要花费更多时间。我想我做错了。

集合parent中有大量文档,大约6000个。每个文档都有一定数量的childs(子节点是另一个集合中包含40000个文档的集合)。 parents & childs通过名为parent_id的文档中的属性相互关联。请参阅以下代码。以下代码大约需要1分钟来执行查询。我不认为mongo应该花那么多时间。

function getChildMaxDocCount(){
    var maxLen = 0;
    var bigSizeParent =  null;
    db.parents.find().forEach(function (parent){
    var currentcount = db.childs.count({parent_id:parent._id});
    if(currcount > maxLen){
        maxLen = currcount;
        bigSizeParent = parent._id;
    }
    });

    printjson({"maxLen":maxLen, "bigSizeParent":bigSizeParent });
}

有没有可行/最佳的方法来实现这一目标?

1 个答案:

答案 0 :(得分:5)

如果我找对你,你想让父母拥有最多的孩子。使用聚合框架很容易实现。当每个子节点只能有一个父节点时,聚合查询看起来像这样

db.childs.aggregate(
  { $group: { _id:"$parent_id", children:{$sum:1} } },
  { $sort: { "children":-1 } },
  { $limit : 1 }
);

哪个文件应该返回如下文件:

 { _id:"SomeParentId", children:15}

如果一个孩子可以拥有多个父母,那么它在很大程度上取决于数据建模查询的样子。

详细了解aggregation framework documentation

编辑:一些解释

聚合管道通过一系列步骤获取所告知的每个文档,其方式是首先处理所有文档,然后将结果文档放入下一步。

第1步:分组

我们将所有文档分组为新文档(虚拟文档,如果需要),并告诉mongod将字段children递增1,以用于具有相同parent_id的每个文档。由于我们指的是当前文档的字段,因此我们需要添加$符号。

第2步:排序

现在我们有一堆文件包含parent_id和这个父项所拥有的子项数,我们按children字段按降序(-1)顺序对其进行排序。

第3步:限制

由于我们只对拥有最多孩子的parent_id感兴趣,我们只让mongod在排序后返回第一个文档。