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
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.
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.
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
Przepraszam, powinny być jaśniejsze. Spróbuję go edytować w ciągu sekundy, ale pierwszy mecz używa indeksu, drugi nie. –