2017-01-04 56 views
2

我在MongoDB中有以下情形:

每条记录​​都有它自己的_id和一个parentId。如果parentId ==“”那么它是一个真正的父记录。如果parentId有一个值,那么该记录实际上是一个指向父记录的孩子。以下显示一位父母及其关联的孩子。

{"_id": ObjectId('586c9d275d2f62e1634978db'), parentId="", count=1, <other fields>} 
{"_id": ObjectId('586c9d275d2f62e163497811'), parentId=ObjectId('586c9d275d2f62e1634978db'), count=3, <other fields>} 

我想查询的地方,我觉得所有的数场,所有的父母和孩子的记录组合在一起排序的父记录。例如,最简单的通过图来说明:

enter image description here

ID6具有被关联到父ID5的最高计数值。接下来的最高计数是关联于母公司ID1 ID2终于ID4是父母,也应该归还所以结果应该是:

ID5,ID1,ID4

HoefMeistert帮我想出了以下查询:

MongoDB sorting on children

db.collection.aggregate(
    [ 
    { 
     $project: { 
     group_id : { $cond : { if: { $ne: [ "$parentId", "" ] }, then: "$parentId", else: "$_id" }}, 
     count :1, 
     field1:1, 
     field2:1 
     } 
    }, 
    { 
     $group: { 
     _id : "$group_id", 
     highest : { $max: "$count" } 
     }, 
     "field1":{"$first":"$field1"}, 
     "field2":{"$first":"$field2"}, 
    }, 
    { 
     $sort: { 
     highest : -1 
     } 
    } 
    ] 
); 

与此查询的问题是,它不返回相关联的父母即在FIELD1和FIELD2图中的ID1和ID5。有没有一种方法可以在小组阶段投射与父母相关的正确字段?否则,如果小组赛阶段返回如下内容:

{'_id': ObjectId('586c9d275d2f62e1634978db'), 'highest': 2} 
{'_id': ObjectId('586c9d0d5d2f62e1634978d5'), 'highest': 1} 
{'_id': ObjectId('586c9d365d2f62e1634978e3'), 'highest': 0} 

如何重新组合后拉回所有上述ID的整个记录​​?即586c9d275d2f62e1634978db,586c9d0d5d2f62e1634978d5,586c9d365d2f62e1634978e3 ??

+0

不介意使用MongoDB的从3.4 –

回答

1

您的查询有错误,field1field2需要是$group字典里:根据你的图上

db.collection.aggregate([ 
    { 
     $project: { 
      group_id: { $cond: { if: { $ne: [ "$parentId", "" ] }, then: "$parentId", else: "$_id" }}, 
      count: 1, 
      field1: 1, 
      field2: 1 
     } 
    }, 
    { 
     $group: { 
     _id: "$group_id", 
     highest: { $max: "$count"}, 
     field1: { "$first": "$field1"}, 
     field2: { "$first":" $field2"}, 
     }, 
    }, 
    { 
     $sort: { 
     highest : -1 
     } 
    } 
]); 

结果:

{ "_id" : "5", "highest" : 5, "field1" : ..., "field2" : ... } 
{ "_id" : "1", "highest" : 3, "field1" : ..., "field2" : ... } 
{ "_id" : "4", "highest" : 1, "field1" : ..., "field2" : ... } 

编辑:

db.collection.aggregate([ 
    { 
     $project: { 
      group_id: { $cond: { if: { $ne: [ "$parentId", "" ] }, then: "$parentId", else: "$_id" }}, 
      count: 1, 
      field1: { $cond: { if: { $ne: [ "$parentId", "" ] }, then: null, else: "$field1" }}, 
      field2: { $cond: { if: { $ne: [ "$parentId", "" ] }, then: null, else: "$field2" }}, 
     } 
    }, 
    { 
     $group: { 
      _id: "$group_id", 
      highest: { $max: "$count"}, 
      field1: { "$max": "$field1"}, 
      field2: { "$max":"$field2"}, 
     }, 
    }, 
    { 
     $sort: { 
      highest : -1 
     } 
    } 
]);

有了这个编辑,在小组阶段只有父母将具有值为field1,field2,其他文件将具有null值。比我们可以做一个$max他们,以获得唯一的价值,父母的价值。

结果就会像上面一样,和field1field2将有从母文件值

+0

的Sergiu嗨功能,感谢指出了这一点,这是一个错字原代码在里面包含它们。然而这不是问题。投射的领域仍然可能不属于父母 –

+0

我看,让我们尝试改进,检查我的编辑 – sergiuz

+0

尼斯是的,看起来像它会工作谢谢Sergiu。之前我接受这个答案,虽然我只是看着graphLookup功能,我认为可能会提供更优雅的解决方案。 –