Mongodb Explain for Aggregation framework

118

Czy istnieje funkcja wyjaśniająca dla struktury agregacji w MongoDB? Nie widzę tego w dokumentacji.

Jeśli nie, to czy istnieje inny sposób sprawdzenia, jak działa zapytanie w ramach agregacji?

Wiem, że po prostu znajdź

db.collection.find().explain()

Ale w ramach agregacji pojawia się błąd

db.collection.aggregate(
    { $project : { "Tags._id" : 1 }},
    { $unwind : "$Tags" },
    { $match: {$or: [{"Tags._id":"tag1"},{"Tags._id":"tag2"}]}},
    { 
        $group: 
        { 
            _id : { id: "$_id"},
            "count": { $sum:1 } 
        }
    },
    { $sort: {"count":-1}}
).explain()
SCB
źródło

Odpowiedzi:

172

Począwszy od MongoDB w wersji 3.0, wystarczy zmienić kolejność z

collection.aggregate(...).explain()

do

collection.explain().aggregate(...)

da pożądane rezultaty (dokumentacja tutaj ).

W przypadku starszych wersji> = 2,6 należy użyć explainopcji dla operacji potoku agregacji

explain:true

db.collection.aggregate([
    { $project : { "Tags._id" : 1 }},
    { $unwind : "$Tags" },
    { $match: {$or: [{"Tags._id":"tag1"},{"Tags._id":"tag2"}]}},
    { $group: { 
        _id : "$_id",
        count: { $sum:1 } 
    }},
    {$sort: {"count":-1}}
  ],
  {
    explain:true
  }
)

Ważnym czynnikiem przy agregacji ram jest to, że indeks może być użyty tylko do pobierania danych początkowych do rurociągu (np wykorzystania $match, $sort, $geonearna początku przewodu rurowego), jak również późniejsze $lookupi $graphLookupetapy. Po pobraniu danych do potoku agregacji w celu ich przetworzenia (np. Przejścia przez etapy, takie jak $project, $unwindi $group) dalsza manipulacja będzie przechowywana w pamięci (prawdopodobnie przy użyciu plików tymczasowych, jeśli allowDiskUseopcja jest ustawiona).

Optymalizacja rurociągów

Ogólnie rzecz biorąc, możesz zoptymalizować potoki agregacji przez:

  • Uruchomienie potoku z $matchetapem ograniczenia przetwarzania do odpowiednich dokumentów.
  • Zapewnienie, że początkowe $match/ $sortetapy są obsługiwane przez skuteczny indeks .
  • Filtrowanie danych za pomocą wcześnie $match, $limiti $skip.
  • Minimalizowanie niepotrzebnych etapów i manipulacji dokumentami (być może ponowne rozważenie schematu, jeśli wymagana jest skomplikowana gimnastyka agregująca).
  • Skorzystaj z nowszych operatorów agregacji, jeśli zaktualizowałeś serwer MongoDB. Na przykład MongoDB 3.4 dodano wiele nowych etapów agregacji i wyrażeń, w tym obsługę tablic, ciągów znaków i aspektów.

Istnieje również szereg optymalizacji potoku agregacji, które są wykonywane automatycznie w zależności od wersji serwera MongoDB. Na przykład sąsiednie etapy mogą być łączone i / lub zmieniane w kolejności w celu usprawnienia wykonania bez wpływu na wyniki wyjściowe.

Ograniczenia

Podobnie jak w MongoDB 3.4, explainopcja Aggregation Framework zapewnia informacje o przetwarzaniu potoku, ale nie obsługuje tego samego poziomu szczegółowości, co executionStatstryb find()zapytania. Jeśli koncentrujesz się na optymalizacji początkowego wykonywania zapytania, prawdopodobnie korzystne będzie przejrzenie równoważnego find().explain()zapytania z executionStatslub allPlansExecutionszczegółowością .

W narzędziu do śledzenia problemów MongoDB dostępnych jest kilka żądań funkcji, które należy obserwować / głosować za bardziej szczegółowymi statystykami wykonania, aby pomóc zoptymalizować / profilować potoki agregacji:

Stennie
źródło
Dzięki za informację, zobaczę, czy mogę wprowadzić jakieś zmiany.
SCB
Czy obiekt nie powinien $sortznajdować się wewnątrz tablicy potoków?
JohnnyHK
@JohnnyHK: Tak. Jacyś mili ludzie "poprawiają" odpowiedź niepoprawnie :).
Stennie
Ale to nie jest przekazanie „
Statutu
1
@KanagaveluSugumar Zaktualizowałem odpowiedź, dodając wyjaśnienie dotyczące explainograniczeń struktury agregacji, a także odpowiednich żądań funkcji dotyczących dodatkowych statystyk wykonania.
Stennie,
29

Począwszy od wersji 2.6.x mongodb pozwala użytkownikom na wyjaśnianie za pomocą frameworka agregacji .

Wystarczy dodać wyjaśnienie: prawda

db.records.aggregate(
  [ ...your pipeline...],
  { explain: true }
)

Dzięki Rafie wiem, że dało się to zrobić nawet w 2.4, ale tylko przez runCommand(). Ale teraz możesz również użyć agregatu.

Salvador Dali
źródło
5
Właściwie możesz wyjaśnić agregacje za pomocą db.collection.runCommand('aggregate', {pipeline: [PIPELINE], explain: true})od MongoDB 2.2.
Rafa
1
Masz rację, w 2.2 i 2.4 agregacje można wyjaśnić tylko za pomocą runCommand. Dzięki za poparcie.
Rafa
3
Chociaż opcja istnieje technicznie za pośrednictwem runCommand przed wersją 2.6, nie gwarantuje ona uzyskania poprawnych wyników i nie powinna być zalecana. Naprawdę powinieneś używać tego tylko w 2.5.3 lub nowszej (i spodziewaj się, że przed wydaniem produkcyjnym 2.6 nadal mogą czaić się błędy).
Stennie,
20

Ramy agregacji

Struktura agregacji to zestaw narzędzi analitycznych, MongoDBktóre pozwalają nam uruchamiać różnego rodzaju raporty lub analizy dokumentów w jednej lub kilku kolekcjach. Oparty na idei rurociągu. Pobieramy dane wejściowe z MongoDBkolekcji i przekazujemy dokumenty z tej kolekcji przez jeden lub więcej etapów, z których każdy wykonuje inną operację na swoich danych wejściowych. Każdy etap przyjmuje jako dane wejściowe bez względu na to, jaki etap przed nim wyprodukował jako dane wyjściowe. A wejścia i wyjścia dla wszystkich etapów to strumień dokumentów. Każdy etap ma określoną pracę, którą wykonuje. Oczekuje określonej formy dokumentu i generuje określone wyjście, które samo w sobie jest strumieniem dokumentów. Na końcu potoku uzyskujemy dostęp do wyjścia.

etap struktury agregacji

Poszczególnym etapem jest jednostka przetwarzania danych. Każdy etap przyjmuje jako dane wejściowe strumień dokumentów pojedynczo, przetwarza każdy dokument pojedynczo i generuje strumień wyjściowy dokumentów. Znowu, pojedynczo. Każdy stopień zawiera zestaw pokręteł lub regulatorów, które możemy kontrolować, aby sparametryzować scenę, aby wykonać dowolne zadanie, które chcemy wykonać. Tak więc etap wykonuje ogólne zadanie - pewnego rodzaju zadanie ogólnego przeznaczenia i parametryzuje scenę dla określonego zestawu dokumentów, z którymi pracujemy. I dokładnie, co chcielibyśmy, aby ten etap robił z tymi dokumentami. Te strojenie zwykle przybierają postać operatorów, które możemy dostarczyć, które modyfikują pola, wykonują operacje arytmetyczne, przekształcają dokumenty lub wykonują jakieś zadania akumulacyjne, a także wiele innych rzeczy. Często zdarza się, że

ten sam typ etapu wiele razy w ramach jednego potoku

np. możemy chcieć wykonać początkowy filtr, abyśmy nie musieli przekazywać całej kolekcji do naszego potoku. Ale później, po pewnym dodatkowym przetwarzaniu, chcesz ponownie filtrować przy użyciu innego zestawu kryteriów. Podsumowując, potok działa z MongoDBkolekcją. Składają się z etapów, z których każdy wykonuje inne zadanie przetwarzania danych na swoim wejściu i tworzy dokumenty jako dane wyjściowe, które mają być przekazane do następnego etapu. I w końcu na końcu potoku generowane jest wyjście, które możemy zrobić w naszej aplikacji. W wielu przypadkach konieczne jest wielokrotne włączanie tego samego typu etapu w ramach pojedynczego potoku.

Zameer
źródło
dziękuję, lepsze zrozumienie pomogło.
Arun Pratap Singh