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

tre*_*rex 2 query-optimization mongodb

我对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 });
}
Run Code Online (Sandbox Code Playgroud)

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

Mar*_*erg 5

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

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

哪个应该返回如下文档:

 { _id:"SomeParentId", children:15}
Run Code Online (Sandbox Code Playgroud)

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

有关详细信息,请查看聚合框架文档.

编辑:一些解释

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

第1步:分组

我们将所有文档分组为新文档(虚拟文档,如果需要),并告诉mongod将children每个文档的字段增加一个parent_id.由于我们指的是当前文档的字段,我们需要添加一个$符号.

第2步:排序

既然我们有一堆文件来保存parent_id和这个父项具有的子项数,我们children按字母-1顺序按递减顺序对它进行排序.

第3步:限制

由于我们只关心parent_id哪个孩子最多,我们只让mongod在排序后返回第一个文件.