diff options
author | Mihai Andrei <mihai.andrei@mongodb.com> | 2019-12-02 19:49:47 +0000 |
---|---|---|
committer | evergreen <evergreen@mongodb.com> | 2019-12-02 19:49:47 +0000 |
commit | 159d19b1d3b0164d0096ce225f987da4610cc5db (patch) | |
tree | 41c321fd8cf90f23e80442a98ed009ba77c2238a /src/mongo/db/pipeline/pipeline.cpp | |
parent | 139481dc1a1336b5711e0f4903107008b13d5ff3 (diff) | |
download | mongo-159d19b1d3b0164d0096ce225f987da4610cc5db.tar.gz |
SERVER-21784 Track 'nReturned' and 'executionTimeMillis' execution stats for each aggregation pipeline stage and expose via explain
Diffstat (limited to 'src/mongo/db/pipeline/pipeline.cpp')
-rw-r--r-- | src/mongo/db/pipeline/pipeline.cpp | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/src/mongo/db/pipeline/pipeline.cpp b/src/mongo/db/pipeline/pipeline.cpp index 6296810a241..4dc6eb2a972 100644 --- a/src/mongo/db/pipeline/pipeline.cpp +++ b/src/mongo/db/pipeline/pipeline.cpp @@ -55,6 +55,21 @@ namespace mongo { +namespace { + +// Given a serialized document source, appends execution stats 'nReturned' and +// 'executionTimeMillisEstimate' to it. +Value appendExecStats(Value docSource, const CommonStats& stats) { + invariant(docSource.getType() == BSONType::Object); + MutableDocument doc(docSource.getDocument()); + auto nReturned = static_cast<long long>(stats.advanced); + auto executionTimeMillisEstimate = static_cast<long long>(stats.executionTimeMillis); + doc.addField("nReturned", Value(nReturned)); + doc.addField("executionTimeMillisEstimate", Value(executionTimeMillisEstimate)); + return Value(doc.freeze()); +} +} // namespace + /** * Enabling the disablePipelineOptimization fail point will stop the aggregate command from * attempting to optimize the pipeline or the pipeline stages. Neither DocumentSource::optimizeAt() @@ -466,8 +481,17 @@ boost::optional<Document> Pipeline::getNext() { vector<Value> Pipeline::writeExplainOps(ExplainOptions::Verbosity verbosity) const { vector<Value> array; - for (SourceContainer::const_iterator it = _sources.begin(); it != _sources.end(); ++it) { - (*it)->serializeToArray(array, verbosity); + for (auto&& stage : _sources) { + auto beforeSize = array.size(); + stage->serializeToArray(array, verbosity); + auto afterSize = array.size(); + // Append execution stats to the serialized stage if the specified verbosity is + // 'executionStats' or 'allPlansExecution'. + invariant(afterSize - beforeSize == 1u); + if (verbosity >= ExplainOptions::Verbosity::kExecStats) { + auto serializedStage = array.back(); + array.back() = appendExecStats(serializedStage, stage->getCommonStats()); + } } return array; } |