2017-09-10 2 views
0

Ich möchte find alle Dokumente, in denen sCompetitions.length ist größer als competitions.length.Vergleichen Größe von Arrays in einem Array von Objekten

Hier einige Beispieldokumente Dokument:

{ 
    "_id" : ObjectId("59b28f432b4353d3f311dd1b"), 
    "name" : "Ford Focus RS 2008", 
    "requirements" : [ 
     { 
      "rankType" : "D1", 
      "competitions" : [ 
       ObjectId("59b151fd2b4353d3f3116827"), 
       ObjectId("59b151fd2b4353d3f3116829") 
      ], 
      "sCompetitions" : [ 
       "Rallye Monte-Carlo", 
       "Rally Sweden" 
      ] 
     }, 
     { 
      "rankType" : "A3", 
      "competitions" : [ 
       ObjectId("59b151fd2b4353d3f3116f6b") 
      ], 
      "sCompetitions" : [ 
       "Rally Italia Sardegna", 
       "Neste Rally Finland" 
      ] 
     } 
    ] 
}, 
{ 
    "_id" : ObjectId("0000b28f432b4353f311dd1b"), 
    "name" : "Ford Focus RS 2012", 
    "requirements" : [ 
     { 
      "rankType" : "D1", 
      "competitions" : [ 
       ObjectId("59b151fd2b4353d3f3116827"), 
       ObjectId("59b151fd2b4353d3f3116829") 
      ], 
      "sCompetitions" : [ 
       "Rallye Monte-Carlo", 
       "Rally Sweden" 
      ] 
     }, 
     { 
      "rankType" : "A3", 
      "competitions" : [ 
       ObjectId("59b151fd2b4353d3f3116f6b"), 
       ObjectId("59b151fd2b4353d3f3116f6b") 
      ], 
      "sCompetitions" : [ 
       "Rally Italia Sardegna", 
       "Neste Rally Finland" 
      ] 
     } 
    ] 
} 

So bei den Proben suchen würde es nur zurückkehren ObjectId("59b28f432b4353d3f311dd1b")

Mein Problem ist, dass requirements ein Array von selbst, so dass ich müsste es irgendwie iterieren

Antwort

1

Keine Notwendigkeit, "iterieren". Alles, was Sie wirklich brauchen, ist eine $anyElementTrue Überprüfung nach der Rückgabe der Ergebnisse von $map. Und Sie können dies tun, alle in einem $redact Aktion:

Model.aggregate([ 
    { "$redact": { 
    "$cond": { 
     "if": { 
     "$anyElementTrue": { 
      "$map": { 
      "input": "$requirements", 
      "as": "r", 
      "in": { 
       "$gt": [ 
       { "$size": "$$r.sCompetitions" }, 
       { "$size": "$$r.competitions" } 
       ] 
      } 
      } 
     } 
     }, 
     "then": "$$KEEP", 
     "else": "$$PRUNE" 
    } 
    }} 
]) 

So ist es ein einfacher Vergleich von $size für jedes Array-Element, und dann, wenn „alle“ dieser Elemente ist true, wird das Dokument „gehalten“ oder auf andere Weise "beschnitten" von den Ergebnissen.

+0

Danke. Aus Neugier, könnte ich einen'OR'-Operator in 'in' verwenden? Z.B. Wenn ich alle Dokumente finden möchte, in denen 'sCompetitions.length' größer ist als' competitions.length' * ODER * 'rankType == 'CC'' – Cornwell

+0

@Cornwell Sie können verwenden, was immer Sie möchten. Der einzige Punkt, der hier einen booleschen Wert für jedes Array-Element zurückgibt. Dies verwendet ['$ gt'] (https://docs.mongodb.com/manual/reference/operator/aggregation/gt/), da dies die Bedingung war, nach der Sie gefragt haben. Aber jeder der [Vergleichsoperatoren] (https://docs.mongodb.com/manual/reference/operator/aggregation-comparison/) oder tatsächlich verschiedene andere, die ebenfalls einen booleschen Wert zurückgeben, können für den gleichen Zweck verwendet werden. –

Verwandte Themen