Mongodb Explain for Aggregation framework


118

Esiste una funzione di spiegazione per il framework di aggregazione in MongoDB? Non riesco a vederlo nella documentazione.

In caso contrario, esiste un altro modo per verificare come viene eseguita una query all'interno del framework di aggregazione?

So che con find devi solo farlo

db.collection.find().explain()

Ma con il framework di aggregazione ottengo un errore

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()

Risposte:


172

A partire da MongoDB versione 3.0, cambiando semplicemente l'ordine da

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

per

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

ti darà i risultati desiderati (documentazione qui ).

Per le versioni precedenti> = 2.6, sarà necessario utilizzare l' explainopzione per le operazioni della pipeline di aggregazione

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

Una considerazione importante con il quadro di aggregazione è che un indice può essere utilizzato solo per recuperare i dati iniziali per una tubazione (ad esempio l'utilizzo di $match, $sort, $geonearall'inizio di una pipeline), così come la successiva $lookupe $graphLookupstadi. Una volta che i dati sono stati recuperati nella pipeline di aggregazione per l'elaborazione (ad esempio passando attraverso fasi come $project, $unwinde $group), un'ulteriore manipolazione sarà in memoria (possibilmente utilizzando file temporanei se l' allowDiskUseopzione è impostata).

Ottimizzazione delle pipeline

In generale, puoi ottimizzare le pipeline di aggregazione:

  • Avvio di una pipeline con una $matchfase per limitare l'elaborazione ai documenti pertinenti.
  • Garantire che le fasi iniziali $match/ $sortsiano supportate da un indice efficiente .
  • Filtraggio dei dati in anticipo utilizzando $match, $limite $skip.
  • Ridurre al minimo le fasi non necessarie e la manipolazione dei documenti (magari riconsiderando il proprio schema se sono necessarie complicate ginnastica di aggregazione).
  • Approfittando dei nuovi operatori di aggregazione se hai aggiornato il tuo server MongoDB. Ad esempio, MongoDB 3.4 ha aggiunto molte nuove fasi ed espressioni di aggregazione, incluso il supporto per lavorare con array, stringhe e facet.

Esistono anche una serie di ottimizzazioni della pipeline di aggregazione che vengono eseguite automaticamente a seconda della versione del server MongoDB. Ad esempio, gli stadi adiacenti possono essere uniti e / o riordinati per migliorare l'esecuzione senza influenzare i risultati di output.

limitazioni

Come in MongoDB 3.4, l' explainopzione Aggregation Framework fornisce informazioni su come viene elaborata una pipeline ma non supporta lo stesso livello di dettaglio della executionStatsmodalità per una find()query. Se ti concentri sull'ottimizzazione dell'esecuzione della query iniziale, probabilmente troverai utile rivedere la find().explain()query equivalente con executionStatso allPlansExecutionverbosity .

Ci sono alcune richieste di funzionalità rilevanti da guardare / votare a favore nel tracker dei problemi di MongoDB per quanto riguarda statistiche di esecuzione più dettagliate per aiutare a ottimizzare / profilare le pipeline di aggregazione:


Grazie per le informazioni, vedremo se posso apportare modifiche.
SCB

L' $sortoggetto non dovrebbe essere all'interno della matrice della pipeline?
JohnnyHK

@JohnnyHK: Sì. Alcune persone gentili stanno "correggendo" la risposta in modo errato :).
Stennie

Ma questo non sta dando le "executionStats"
Kanagavelu Sugumar

1
@KanagaveluSugumar Ho aggiornato la risposta con chiarimenti sui explainlimiti di Aggregation Framework e richieste di funzionalità rilevanti per statistiche di esecuzione aggiuntive.
Stennie

29

A partire dalla versione 2.6.x mongodb consente agli utenti di spiegare con il framework di aggregazione .

Tutto quello che devi fare è aggiungere spiegare: vero

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

Grazie a Rafa so che era possibile fare anche in 2.4, ma solo attraverso runCommand(). Ma ora puoi usare anche aggregato.


5
In realtà, puoi spiegare gli aggregati con db.collection.runCommand('aggregate', {pipeline: [PIPELINE], explain: true})MongoDB 2.2.
Rafa

1
Hai ragione, in 2.2 e 2.4 puoi spiegare gli aggregati solo tramite runCommand. Grazie per il voto positivo.
Rafa

3
Sebbene l'opzione tecnicamente esista tramite runCommand prima della 2.6, non è garantito che produca risultati corretti e non dovrebbe essere raccomandata. Dovresti davvero usarlo solo nella 2.5.3 o più recente (e aspettarti che potrebbero esserci ancora alcuni bug in agguato prima del rilascio di produzione 2.6).
Stennie

20

Il quadro di aggregazione

Il framework di aggregazione è un insieme di strumenti di analisi all'interno MongoDBche ci consente di eseguire vari tipi di report o analisi sui documenti in una o più raccolte. Basato sull'idea di una pipeline. Prendiamo input da una MongoDBraccolta e passiamo i documenti da quella raccolta attraverso una o più fasi, ognuna delle quali esegue un'operazione diversa sui propri input. Ogni fase prende come input qualunque sia la fase prima di essere prodotta come output. E gli input e gli output per tutte le fasi sono un flusso di documenti. Ogni fase ha un lavoro specifico che fa. Si aspetta una forma specifica di documento e produce un output specifico, che è esso stesso un flusso di documenti. Alla fine della pipeline, abbiamo accesso all'output.

fase del quadro di aggregazione

Una singola fase è un'unità di elaborazione dei dati. Ogni fase prende come input un flusso di documenti uno alla volta, elabora ogni documento uno alla volta e produce il flusso di output dei documenti. Di nuovo, uno alla volta. Ogni stadio fornisce una serie di manopole o sintonizzabili che possiamo controllare per parametrizzare lo stadio per eseguire qualsiasi attività che ci interessa fare. Quindi una fase esegue un'attività generica, un'attività generica di qualche tipo e parametrizza la fase per il particolare set di documenti con cui stiamo lavorando. Ed esattamente quello che vorremmo che quella fase facesse con quei documenti. Questi parametri sintonizzabili assumono tipicamente la forma di operatori che possiamo fornire che modificheranno i campi, eseguiranno operazioni aritmetiche, rimodelleranno i documenti o eseguiranno una sorta di attività di accumulazione così come una vera varietà di altre cose. Spesso, è il caso che noi '

stesso tipo di fase più volte all'interno di una singola pipeline

Ad esempio, potremmo voler eseguire un filtro iniziale in modo da non dover passare l'intera raccolta nella nostra pipeline. Ma, in seguito, dopo alcune elaborazioni aggiuntive, si desidera filtrare nuovamente utilizzando un diverso insieme di criteri. Quindi, per ricapitolare, la pipeline funziona con una MongoDBraccolta. Sono composti da fasi, ognuna delle quali svolge un'attività di elaborazione dati diversa sul proprio input e produce documenti come output da passare alla fase successiva. E infine, alla fine della pipeline, viene prodotto un output che possiamo quindi fare qualcosa all'interno della nostra applicazione. In molti casi, è necessario includere lo stesso tipo di fase, più volte all'interno di una singola pipeline.


grazie, è stato utile per ottenere una migliore comprensione.
Arun Pratap Singh
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.