2015-05-27 3 views
5

Ich arbeite an einem Projekt, das erfordert, dass ich dynamisch eine MongoDB-Abfrage basierend auf vielen Übereinstimmungen (wahrscheinlich ein Potenzial von 100) erstellen kann. Zusätzlich zur Erstellung der richtigen Indizes habe ich mich gefragt, ob es wichtig ist, wie ich die Matches in die Pipeline eingebaut habe. Basiert eines dieser Beispiele auf dem folgenden Beispiel anders oder besser als das andere?MongoDB (3.0) Aggregation: Mehrere Übereinstimmungen vs Eine Übereinstimmung mit mehreren Elementen

Ich nehme an Beispiel 2 würde die Ergebnismenge Widdle unten aber mehr Anrufe sein? Vielleicht macht das Beispiel 1 hinter den Kulissen?

Vielen Dank im Voraus für Ihre Hilfe!

Beispiel 1

db.Test.aggregate(
[  
    { $match: { item1: 'foo1', item2: 'foo2', item3: 'foo3' } } 
]) 

vs

Beispiel 2

db.Test.aggregate(
[  
    { $match: { item1: 'foo1' } }, 
    { $match: { item2: 'foo2' } }, 
    { $match: { item3: 'foo3' } } 
]) 

Ich bezweifle es für diese Frage Rolle, aber wenn relevant werde ich die C# Treiber verwenden für meine Umsetzung.

+0

Interessante Frage ... haben Sie es geschafft, zu finden und zu beantworten? – Moppo

+0

Ich wäre auch neugierig zu wissen! –

Antwort

1

fand ich die folgenden Informationen in MongoDB's documentation:

$match + $match Koaleszenz

Wenn ein $match sofort ein anderes $match folgt, können die zwei Stufen in einem einzigen $ Spiel verschmelzen die Bedingungen mit einer Kombination $and. Zum Beispiel enthält eine Pipeline die folgende Sequenz:

{ $match: { year: 2014 } }, 
{ $match: { status: "A" } } 

Dann wird die zweite $ paßt Stufe in die ersten $ Match Bühne verschmelzen kann und in einer einzigen $ Spiel Phase führen:

{ $match: { $and: [ { "year" : 2014 }, { "status" : "A" } ] } } 

Aus dies kann ich sagen, dass die Verwendung mehrerer $match in einem rohen ist streng gleichwertig als mit einem einzigen $match mit mehreren Feldern.

Ich bin unsicher, aber warum fügt die Optimierungs-Engine hier einen $and Operator hinzu. Laut this answer sollte es nicht notwendig sein, daher denke ich, dass es ignoriert werden kann. Jemand kann bestätigen?

0

Ich fragte mich heute dasselbe und stolperte über die Antwort von Romain.Obwohl ich das für mich selbst sehen wollte, was leicht mit einer Erklärung auf beiden Aggregaten geschehen kann;

db.verpakking.explain().aggregate([ 
    { "$match": {type: "VERPAKT"} }, 
    { "$match": {ras: "CherryStar"} }, 
]); 

, die in der folgenden Ausgabe führt:

{ 
    "waitedMS" : NumberLong(0), 
    "stages" : [ 
    { 
     "$cursor" : { 
     "query" : { 
      "$and" : [ 
      { 
       "type" : "VERPAKT" 
      }, 
      { 
       "ras" : "CherryStar" 
      } 
      ] 
     }, 
     "queryPlanner" : { 
      "plannerVersion" : NumberInt(1), 
      "namespace" : "denberk.verpakking", 
      "indexFilterSet" : false, 
      "parsedQuery" : { 
      "$and" : [ 
       { 
       "ras" : { 
        "$eq" : "CherryStar" 
       } 
       }, 
       { 
       "type" : { 
        "$eq" : "VERPAKT" 
       } 
       } 
      ] 
      }, 
      "winningPlan" : { 
      "stage" : "COLLSCAN", 
      "filter" : { 
       "$and" : [ 
       { 
        "ras" : { 
        "$eq" : "CherryStar" 
        } 
       }, 
       { 
        "type" : { 
        "$eq" : "VERPAKT" 
        } 
       } 
       ] 
      }, 
      "direction" : "forward" 
      }, 
      "rejectedPlans" : [ 

      ] 
     } 
     } 
    } 
    ], 
    "ok" : NumberInt(1) 
} 

Während

db.verpakking.explain().aggregate([ 
{ "$match": {type: "VERPAKT", ras: "CherryStar"} }, 
]); 

Ergebnisse in der Ausgabe:

{ 
    "waitedMS" : NumberLong(0), 
    "stages" : [ 
    { 
     "$cursor" : { 
     "query" : { 
      "type" : "VERPAKT", 
      "ras" : "CherryStar" 
     }, 
     "queryPlanner" : { 
      "plannerVersion" : NumberInt(1), 
      "namespace" : "denberk.verpakking", 
      "indexFilterSet" : false, 
      "parsedQuery" : { 
      "$and" : [ 
       { 
       "ras" : { 
        "$eq" : "CherryStar" 
       } 
       }, 
       { 
       "type" : { 
        "$eq" : "VERPAKT" 
       } 
       } 
      ] 
      }, 
      "winningPlan" : { 
      "stage" : "COLLSCAN", 
      "filter" : { 
       "$and" : [ 
       { 
        "ras" : { 
        "$eq" : "CherryStar" 
        } 
       }, 
       { 
        "type" : { 
        "$eq" : "VERPAKT" 
        } 
       } 
       ] 
      }, 
      "direction" : "forward" 
      }, 
      "rejectedPlans" : [ 

      ] 
     } 
     } 
    } 
    ], 
    "ok" : NumberInt(1) 
} 

Wie Sie dies genau das gleiche ist zu sehen, außer für den "query" Teil (whi ch ist normal, da unsere Abfrage unterschiedlich war). Dies beweist, dass die analysierte Abfrage genau gleich ist, wenn Sie zwei separate aufeinanderfolgende $ match-pipelines oder eine kombinierte $ match-pipeline verwenden.

Verwandte Themen