diff options
Diffstat (limited to 'src/mongo/db/pipeline')
-rw-r--r-- | src/mongo/db/pipeline/document_source_lookup.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/pipeline/expression.cpp | 6 | ||||
-rw-r--r-- | src/mongo/db/pipeline/expression_context.cpp | 13 | ||||
-rw-r--r-- | src/mongo/db/pipeline/expression_context.h | 41 |
4 files changed, 59 insertions, 3 deletions
diff --git a/src/mongo/db/pipeline/document_source_lookup.cpp b/src/mongo/db/pipeline/document_source_lookup.cpp index 7eb2f9d7169..496c641b969 100644 --- a/src/mongo/db/pipeline/document_source_lookup.cpp +++ b/src/mongo/db/pipeline/document_source_lookup.cpp @@ -674,8 +674,10 @@ void DocumentSourceLookUp::resolveLetVariables(const Document& localDoc, Variabl void DocumentSourceLookUp::initializeResolvedIntrospectionPipeline() { copyVariablesToExpCtx(_variables, _variablesParseState, _fromExpCtx.get()); + _fromExpCtx->startExpressionCounters(); _resolvedIntrospectionPipeline = Pipeline::parse(_resolvedPipeline, _fromExpCtx, lookupPipeValidator); + _fromExpCtx->stopExpressionCounters(); } void DocumentSourceLookUp::serializeToArray( diff --git a/src/mongo/db/pipeline/expression.cpp b/src/mongo/db/pipeline/expression.cpp index 7b53cd77eeb..c63c5fde288 100644 --- a/src/mongo/db/pipeline/expression.cpp +++ b/src/mongo/db/pipeline/expression.cpp @@ -46,6 +46,7 @@ #include "mongo/db/jsobj.h" #include "mongo/db/pipeline/expression_context.h" #include "mongo/db/query/datetime/date_time_support.h" +#include "mongo/db/stats/counters.h" #include "mongo/platform/bits.h" #include "mongo/platform/decimal128.h" #include "mongo/util/regex_util.h" @@ -123,6 +124,8 @@ void Expression::registerExpression( str::stream() << "Duplicate expression (" << key << ") registered.", op == parserMap.end()); parserMap[key] = {parser, requiredMinVersion}; + // Add this expression to the global map of operator counters for expressions. + operatorCountersAggExpressions.addAggExpressionCounter(key); } intrusive_ptr<Expression> Expression::parseExpression( @@ -155,6 +158,9 @@ intrusive_ptr<Expression> Expression::parseExpression( << " for more information.", !expCtx->maxFeatureCompatibilityVersion || !entry.requiredMinVersion || (*entry.requiredMinVersion <= *expCtx->maxFeatureCompatibilityVersion)); + + // Increment the counter for this expression in the current context. + expCtx->incrementAggExprCounter(opName); return entry.parser(expCtx, obj.firstElement(), vps); } diff --git a/src/mongo/db/pipeline/expression_context.cpp b/src/mongo/db/pipeline/expression_context.cpp index 5bfc56283f7..26c9854160f 100644 --- a/src/mongo/db/pipeline/expression_context.cpp +++ b/src/mongo/db/pipeline/expression_context.cpp @@ -215,21 +215,28 @@ intrusive_ptr<ExpressionContext> ExpressionContext::copyWith( } void ExpressionContext::startExpressionCounters() { - if (!_expressionCounters) { + if (enabledCounters && !_expressionCounters) { _expressionCounters = boost::make_optional<ExpressionCounters>({}); } } void ExpressionContext::incrementMatchExprCounter(StringData name) { - if (_expressionCounters) { + if (enabledCounters && _expressionCounters) { ++_expressionCounters.get().matchExprCountersMap[name]; } } +void ExpressionContext::incrementAggExprCounter(StringData name) { + if (enabledCounters && _expressionCounters) { + ++_expressionCounters.get().aggExprCountersMap[name]; + } +} + void ExpressionContext::stopExpressionCounters() { - if (_expressionCounters) { + if (enabledCounters && _expressionCounters) { operatorCountersMatchExpressions.mergeCounters( _expressionCounters.get().matchExprCountersMap); + operatorCountersAggExpressions.mergeCounters(_expressionCounters.get().aggExprCountersMap); } _expressionCounters = boost::none; } diff --git a/src/mongo/db/pipeline/expression_context.h b/src/mongo/db/pipeline/expression_context.h index 341bc4317cb..8ab69171792 100644 --- a/src/mongo/db/pipeline/expression_context.h +++ b/src/mongo/db/pipeline/expression_context.h @@ -110,6 +110,15 @@ public: }; /** + * The structure ExpressionCounters encapsulates counters for match, aggregate, and other + * expression types as seen in end-user queries. + */ + struct ExpressionCounters { + StringMap<uint64_t> aggExprCountersMap; + StringMap<uint64_t> matchExprCountersMap; + }; + + /** * Constructs an ExpressionContext to be used for Pipeline parsing and evaluation. * 'resolvedNamespaces' maps collection names (not full namespaces) to ResolvedNamespaces. */ @@ -316,11 +325,20 @@ public: void incrementMatchExprCounter(StringData name); /** + * Increment the counter for the aggregate expression with a given name. + */ + void incrementAggExprCounter(StringData name); + + /** * Merge expression counters from the current expression context into the global maps * and stop counting. */ void stopExpressionCounters(); + bool expressionCountersAreActive() { + return _expressionCounters.is_initialized(); + } + // The explain verbosity requested by the user, or boost::none if no explain was requested. boost::optional<ExplainOptions::Verbosity> explain; @@ -390,6 +408,29 @@ public: // True if this ExpressionContext is used to parse a collection validator expression. bool isParsingCollectionValidator = false; + // Indicates where there is any chance this operation will be profiled. Must be set at + // construction. + const bool mayDbProfile = true; + + // These fields can be used in a context when API version validations were not enforced during + // parse time (Example creating a view or validator), but needs to be enforce while querying + // later. + bool exprUnstableForApiV1 = false; + bool exprDeprectedForApiV1 = false; + + // Tracks whether the collator to use for the aggregation matches the default collation of the + // collection or view. For collectionless aggregates this is set to 'kNoDefaultCollation'. + enum class CollationMatchesDefault { kNoDefault, kYes, kNo }; + CollationMatchesDefault collationMatchesDefault = CollationMatchesDefault::kNoDefault; + + // When non-empty, contains the unmodified user provided aggregation command. + BSONObj originalAggregateCommand; + + // True if the expression context is the original one for a given pipeline. + // False if another context is created for the same pipeline. Used to disable duplicate + // expression counting. + bool enabledCounters = true; + protected: static const int kInterruptCheckPeriod = 128; |