2017-01-04 1 views
2

Ich habe das folgende Szenario in MongoDB:

Jeder Datensatz hat seine eigene _id und eine ParentId. Wenn parentId == "", dann ist es ein wahrer Eltern-Datensatz. Wenn die parentId einen Wert hat, ist dieser Datensatz tatsächlich ein Kind, das auf den übergeordneten Datensatz verweist. Das folgende zeigt ein Elternteil und sein verbundenes Kind.

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

wollte ich eine Abfrage aus, indem ich durch das Zählfeld sortiert alle übergeordneten Datensätzen zu finden, wo alle Eltern und die untergeordneten Datensätze zusammen gruppiert sind. Zum Beispiel erklärt am einfachsten über Diagramm:

enter image description here

ID6 den höchsten Zählwert hat, der Mutter ID5 zugeordnet ist. Die nächsthöhere Zählung ID2, die Mutter ID1 zugeordnet ist schließlich ID4 ist ein Elternteil und auch zurückgegeben werden sollte, so sollten die Ergebnisse sein:

ID5, ID1, ID4

HoefMeistert half mir mit der folgenden Abfrage kommen :

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

Das Problem bei dieser Abfrage ist, dass es nicht die field1 und field2 den Eltern Ie zugeordnet zurückkehrt ID1 und ID5 im Diagramm. Gibt es eine Möglichkeit, die richtigen Felder, die den Eltern zugeordnet sind, in der Gruppenphase zu projizieren? Andernfalls, wenn die Gruppenphase gibt so etwas wie:

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

Wie kann ich nach den Gruppen Revanche über die ganze Datensätze für alle Ids zurück zu ziehen? I.e. 586c9d275d2f62e1634978db, 586c9d0d5d2f62e1634978d5, 586c9d365d2f62e1634978e3 ??

+0

nicht für den Hinweis aus, es war ein Tippfehler des Original mit Features von mongodb 3.4 –

Antwort

1

Ihre Anfrage hat einen Fehler, field1 und field2 innerhalb des $group dict sein müssen:

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

Ergebnis basierend auf dem Diagramm:

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

Edit:

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

Mit diesem Schnitt, in der Gruppenphase nur die Eltern wird Werte für field1, field2 haben, andere Dokumente werden null Werte haben. Dann können wir eine $max von ihnen tun, um den einzigen Wert, den Elternwert zu erhalten.

Ergebnis wird das gleiche wie oben sein, und field1, field2 haben Werte von Stammdokumenten

+0

Hallo Sergiu dank etwas dagegen, Code enthält sie innen. Dies ist jedoch nicht das Problem. Die projizierten Felder gehören vielleicht immer noch nicht zum Elternteil –

+0

Ich sehe, versuchen wir, das zu verbessern, überprüfen Sie meine Bearbeitung – sergiuz

+0

Nizza ja, das sieht aus wie es funktioniert dank Sergiu. Bevor ich dies als Antwort akzeptiere, schaue ich nur in die graphLookup-Funktionalität, die meiner Meinung nach eine elegantere Lösung bieten kann. –

Verwandte Themen