summaryrefslogtreecommitdiff
path: root/src/mongo/db/pipeline/pipeline.cpp
diff options
context:
space:
mode:
authorMihai Andrei <mihai.andrei@mongodb.com>2019-12-02 19:49:47 +0000
committerevergreen <evergreen@mongodb.com>2019-12-02 19:49:47 +0000
commit159d19b1d3b0164d0096ce225f987da4610cc5db (patch)
tree41c321fd8cf90f23e80442a98ed009ba77c2238a /src/mongo/db/pipeline/pipeline.cpp
parent139481dc1a1336b5711e0f4903107008b13d5ff3 (diff)
downloadmongo-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.cpp28
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;
}