2013-03-25 21 views
6

Od http://docs.mongodb.org/manual/core/indexes/#multikey-indexes możliwe jest utworzenie indeksu na polu tablicy za pomocą indeksu wielostykowego. http://docs.mongodb.org/manual/applications/aggregation/#pipeline-operators-and-indexes zawiera listę niektórych sposobów wykorzystania indeksu w strukturze agregacji. Jednak czasami może być konieczne wykonanie $unwind w polu tablicy, aby wykonać $group. Moje pytanie brzmi, czy indeksy wielotorowe (lub dowolny indeks wykorzystujący takie pole tablicowe) mogą być nadal używane, gdy są one obsługiwane w środku potoku?Rurociąg agregacji i indeksy

Odpowiedz

11

Generalnie tylko operatorzy rurociągów, które mogą być spłaszczone do normalnego zapytania ($match, $limit, $sort i $skip) będą mogli korzystać z indeksów kolekcji. Jest to jeden z powodów, dla których operator $geoNear dodany w 2.4 musi znajdować się na początku potoku.

Po zmutowaniu dokumentów za pomocą $project, $group lub $unwind indeks nie jest już ważny/użyteczny.

Jeśli masz indeks w polu tablicy, możesz go użyć przed $unwind, aby przyspieszyć wybór dokumentów do potoku, a następnie udoskonalić wybrane dokumenty o drugą $match.

Rozważmy dokumentów takich jak:

{ tags: [ 'cat', 'bird', 'blue' ] } 

z indeksem na tags.

Gdybyś tylko chciał grupy tagów zaczynając b następnie można wykonać agregację jak:

{ pipeline: [ 
     { $match : { tags : /^b/ } }, 
     { $unwind : '$tags' }, 
     { $match : { tags : /^b/ } }, 
     /* the rest */ 
    ] } 

Pierwszy $match robi mecz grubego ziarna za pomocą indeksu tags.

Drugi mecz po $unwind nie będzie mógł korzystać z indeksu (powyższy dokument zawiera teraz 3 dokumenty), ale może ocenić każdy z tych dokumentów, aby odfiltrować dodatkowe dokumenty, które zostaną utworzone (aby usunąć {tags: "cat"} z przykładu).

HTH - Rob.

+0

Dzięki za odpowiedź. Jednakże, stwierdzam: "Gdy zmodyfikujesz dokumenty za pomocą ...' $ unwind' indeks przestanie być "sprzeczny z resztą odpowiedzi. Czy możesz wyjaśnić, dlaczego tak jest? – MervS

+0

Przepraszam, powinny być jaśniejsze. Spróbuję go edytować w ciągu sekundy, ale pierwszy mecz używa indeksu, drugi nie. –

0

Hmm @Rob nie dać właściwą odpowiedź, ale widzę, jak on mógł prowadzić cię złą drogę trochę:

Jeśli indeks na polu tablicy nadal można używać go przed i po $ unwind przyspiesza wybór dokumentów do potokowania, a następnie udoskonala wybrane dokumenty.

Zasadniczo daje przykład:

{ pipeline: [ 
     { $match : { tags : /^b/ } }, 
     { $unwind : '$tags' }, 
     { $match : { tags : /^b/ } }, 
     /* the rest */ 
    ] } 

nie użyje indeksu multiklawisz przeszłość $unwind. Będzie więc w stanie wyszukać wszystkie dokumenty ROOT, które mają nazwę znacznika zaczynając od b, ale nie będzie w stanie uzyskać $unwind, a następnie przefiltrować poddokumenty w drugim $match przy użyciu indeksu.

Działa tylko na indeksie przed mutacją.

Tak więc po zmutowaniu dokumentu i załadowaniu go na rurociąg staje się prawie niemożliwe użycie indeksu.