2015-05-27 9 views
5

Pracuję nad projektem, który wymaga od mnie utworzenia dynamicznego zapytania MongoDB w locie w oparciu o wiele dopasowań (prawdopodobnie o potencjale 100). Oprócz tworzenia odpowiednich indeksów zastanawiałem się, czy ma to znaczenie, w jaki sposób zbudowałem dopasowania do potoku. W oparciu o poniższy przykład, czy jeden z tych przykładów działa inaczej lub lepiej niż inny?MongoDB (3.0) Agregacja: Kilka dopasowań vs Jeden mecz z wieloma elementami

Zakładam, że Przykład 2 spowodowałby poszerzenie zestawu wyników, ale czy będzie więcej połączeń? Może to właśnie robi przykład 1 za kulisami?

Z góry dziękuję za pomoc!

Przykład 1

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

vs

Przykład 2

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

Wątpię znaczenia na to pytanie, ale w razie potrzeby będzie używać sterownik C# moje wdrożenie.

+0

Interesujące pytanie ... czy udało Ci się znaleźć i odpowiedzieć? – Moppo

+0

Chciałbym również wiedzieć! –

Odpowiedz

1

znalazłem następujące informacje w MongoDB's documentation:

$match + $match koalescencji

Kiedy $match natychmiast następuje kolejny $match, dwa etapy można łączyć w jeden $ meczu łączącej warunki z $and. Na przykład, rurociąg zawiera następującą sekwencję:

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

Wtedy drugi etap $ mecz można łączyć w pierwszym etapie $ Mecz i prowadzić w jednym etapie $ mecz:

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

Od to mogę powiedzieć, że użycie kilku $match w raw jest ściśle równoważne niż użycie pojedynczego $match z wieloma polami.

Nie jestem pewien, dlaczego mechanizm optymalizacji dodaje tutaj operatora $and. Według this answer nie powinno to być konieczne, dlatego uważam, że można go zignorować. Ktoś może potwierdzić?

0

Zastanawiam się dzisiaj nad tym samym i natknąłem się na odpowiedź Romaina.Chociaż chciałem to zobaczyć samemu, co można łatwo zrobić za pomocą wyjaśnienia obu agregatów;

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

co skutkuje w następujący wynik:

{ 
    "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) 
} 

Podczas gdy

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

Wyniki produkcji:

{ 
    "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) 
} 

Jak widać jest to dokładnie to samo, z wyjątkiem części "zapytania" (whi ch jest normalne, ponieważ nasze zapytanie było inne niż). Świadczy to o tym, że niezależnie od tego, czy używasz dwóch oddzielnych, kolejnych potoków-potoków $, czy jednego połączonego potoku-przebiegu, przetworzone zapytanie będzie dokładnie takie samo.

Powiązane problemy