mirror of
https://github.com/mongodb/mongo.git
synced 2024-12-01 09:32:32 +01:00
SERVER-40090 DISTINCT_SCAN is only used when certain format of $group _id is specified
This commit is contained in:
parent
b2869d11c9
commit
20c0cc8c93
@ -543,6 +543,18 @@ assertResultsMatchWithAndWithoutHintandIndexes(pipeline, [{_id: 1}, {_id: 2}, {_
|
||||
explain = coll.explain().aggregate(pipeline);
|
||||
assert.eq(null, getAggPlanStage(explain, "DISTINCT_SCAN"), explain);
|
||||
|
||||
//
|
||||
// Verify that a $sort-$group pipeline with a $first accumulator can use DISTINCT_SCAN, even when
|
||||
// the group _id field is a singleton object instead of a fieldPath.
|
||||
//
|
||||
pipeline = [{$sort: {a: 1, b: 1}}, {$group: {_id: {v: "$a"}, accum: {$first: "$b"}}}];
|
||||
assertResultsMatchWithAndWithoutHintandIndexes(
|
||||
pipeline, [{_id: {v: null}, accum: null}, {_id: {v: 1}, accum: 1}, {_id: {v: 2}, accum: 2}]);
|
||||
explain = coll.explain().aggregate(pipeline);
|
||||
assert.neq(null, getAggPlanStage(explain, "DISTINCT_SCAN"), explain);
|
||||
assert.eq({a: 1, b: 1, c: 1}, getAggPlanStage(explain, "DISTINCT_SCAN").keyPattern);
|
||||
assert.eq(null, getAggPlanStage(explain, "SORT"), explain);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// We execute all the collation-related tests three times with three different configurations
|
||||
// (no index, index without collation, index with collation).
|
||||
|
@ -762,12 +762,11 @@ bool DocumentSourceGroup::canRunInParallelBeforeWriteStage(
|
||||
|
||||
std::unique_ptr<GroupFromFirstDocumentTransformation>
|
||||
DocumentSourceGroup::rewriteGroupAsTransformOnFirstDocument() const {
|
||||
if (!_idFieldNames.empty()) {
|
||||
if (_idExpressions.size() != 1) {
|
||||
// This transformation is only intended for $group stages that group on a single field.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
invariant(_idExpressions.size() == 1);
|
||||
auto fieldPathExpr = dynamic_cast<ExpressionFieldPath*>(_idExpressions.front().get());
|
||||
if (!fieldPathExpr || !fieldPathExpr->isRootFieldPath()) {
|
||||
return nullptr;
|
||||
@ -794,7 +793,18 @@ DocumentSourceGroup::rewriteGroupAsTransformOnFirstDocument() const {
|
||||
}
|
||||
|
||||
std::vector<std::pair<std::string, boost::intrusive_ptr<Expression>>> fields;
|
||||
fields.push_back(std::make_pair("_id", ExpressionFieldPath::create(pExpCtx.get(), groupId)));
|
||||
|
||||
boost::intrusive_ptr<Expression> idField;
|
||||
// The _id field can be specified either as a fieldpath (ex. _id: "$a") or as a singleton
|
||||
// object (ex. _id: {v: "$a"}).
|
||||
if (_idFieldNames.empty()) {
|
||||
idField = ExpressionFieldPath::create(pExpCtx.get(), groupId);
|
||||
} else {
|
||||
invariant(_idFieldNames.size() == 1);
|
||||
idField = ExpressionObject::create(pExpCtx.get(),
|
||||
{{_idFieldNames.front(), _idExpressions.front()}});
|
||||
}
|
||||
fields.push_back(std::make_pair("_id", idField));
|
||||
|
||||
for (auto&& accumulator : _accumulatedFields) {
|
||||
fields.push_back(std::make_pair(accumulator.fieldName, accumulator.expr.argument));
|
||||
|
Loading…
Reference in New Issue
Block a user