summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--jstests/core/clustered_collection_collation.js16
-rw-r--r--jstests/core/index_filter_commands.js4
-rw-r--r--jstests/core/profile_findandmodify.js2
-rw-r--r--jstests/core/timeseries/timeseries_bucket_index.js2
-rw-r--r--jstests/core/timeseries/timeseries_id_range.js30
-rw-r--r--jstests/libs/analyze_plan.js4
-rw-r--r--jstests/libs/clustered_collections/clustered_collection_bounded_scan_common.js32
-rw-r--r--jstests/libs/clustered_collections/clustered_collection_hint_common.js20
-rw-r--r--src/mongo/db/exec/collection_scan.cpp12
-rw-r--r--src/mongo/db/exec/collection_scan.h2
10 files changed, 68 insertions, 56 deletions
diff --git a/jstests/core/clustered_collection_collation.js b/jstests/core/clustered_collection_collation.js
index 23fcb82277d..9b9c11f428c 100644
--- a/jstests/core/clustered_collection_collation.js
+++ b/jstests/core/clustered_collection_collation.js
@@ -195,7 +195,7 @@ validateClusteredCollectionHint(collated, {
expectedNReturned: 2,
cmd: {find: collatedName, hint: {_id: 1}, min: {_id: "a"}, max: {_id: "C"}},
expectedWinningPlanStats: {
- stage: "COLLSCAN",
+ stage: "CLUSTERED_IXSCAN",
direction: "forward",
minRecord: collatedEncodings["a"],
maxRecord: collatedEncodings["C"]
@@ -209,7 +209,7 @@ validateClusteredCollectionHint(noncollated, {
expectedNReturned: 3, // "a", "b" and "B"
cmd: {find: noncollatedName, hint: {_id: 1}, min: {_id: "A"}, max: {_id: "c"}},
expectedWinningPlanStats:
- {stage: "COLLSCAN", direction: "forward", minRecord: "A", maxRecord: "c"}
+ {stage: "CLUSTERED_IXSCAN", direction: "forward", minRecord: "A", maxRecord: "c"}
});
// Strings with incompatible collation.
@@ -241,12 +241,14 @@ assert.commandFailedWithCode(
validateClusteredCollectionHint(collated, {
expectedNReturned: 2,
cmd: {find: collatedName, hint: {_id: 1}, min: {_id: 5}, max: {_id: 11}},
- expectedWinningPlanStats: {stage: "COLLSCAN", direction: "forward", minRecord: 5, maxRecord: 11}
+ expectedWinningPlanStats:
+ {stage: "CLUSTERED_IXSCAN", direction: "forward", minRecord: 5, maxRecord: 11}
});
validateClusteredCollectionHint(noncollated, {
expectedNReturned: 2,
cmd: {find: noncollatedName, hint: {_id: 1}, min: {_id: 5}, max: {_id: 11}},
- expectedWinningPlanStats: {stage: "COLLSCAN", direction: "forward", minRecord: 5, maxRecord: 11}
+ expectedWinningPlanStats:
+ {stage: "CLUSTERED_IXSCAN", direction: "forward", minRecord: 5, maxRecord: 11}
});
// Numeric with incompatible collation.
@@ -259,7 +261,8 @@ validateClusteredCollectionHint(collated, {
max: {_id: 11},
collation: incompatibleCollation
},
- expectedWinningPlanStats: {stage: "COLLSCAN", direction: "forward", minRecord: 5, maxRecord: 11}
+ expectedWinningPlanStats:
+ {stage: "CLUSTERED_IXSCAN", direction: "forward", minRecord: 5, maxRecord: 11}
});
validateClusteredCollectionHint(noncollated, {
expectedNReturned: 2,
@@ -270,6 +273,7 @@ validateClusteredCollectionHint(noncollated, {
max: {_id: 11},
collation: incompatibleCollation
},
- expectedWinningPlanStats: {stage: "COLLSCAN", direction: "forward", minRecord: 5, maxRecord: 11}
+ expectedWinningPlanStats:
+ {stage: "CLUSTERED_IXSCAN", direction: "forward", minRecord: 5, maxRecord: 11}
});
})();
diff --git a/jstests/core/index_filter_commands.js b/jstests/core/index_filter_commands.js
index ea97aefed48..fd48c095028 100644
--- a/jstests/core/index_filter_commands.js
+++ b/jstests/core/index_filter_commands.js
@@ -163,8 +163,8 @@ assert.commandWorked(explain);
const winningPlan = getWinningPlan(explain.queryPlanner);
const collectionIsClustered = ClusteredCollectionUtil.areAllCollectionsClustered(db.getMongo());
if (collectionIsClustered) {
- assert(isCollscan(db, getWinningPlan(explain.queryPlanner)),
- "Expected collscan: " + tojson(explain));
+ assert(isClusteredIxscan(db, getWinningPlan(explain.queryPlanner)),
+ "Expected clustered ixscan: " + tojson(explain));
} else {
engineSpecificAssertion(
isIdhack(db, winningPlan), isIdIndexScan(db, winningPlan, "FETCH"), db, winningPlan);
diff --git a/jstests/core/profile_findandmodify.js b/jstests/core/profile_findandmodify.js
index 11aa91f21dc..db8a615571b 100644
--- a/jstests/core/profile_findandmodify.js
+++ b/jstests/core/profile_findandmodify.js
@@ -115,7 +115,7 @@ for (var i = 0; i < 3; i++) {
}
const expectedKeysExamined = collectionIsClustered ? 0 : 1;
-const expectedPlan = collectionIsClustered ? "COLLSCAN" : "IDHACK";
+const expectedPlan = collectionIsClustered ? "CLUSTERED_IXSCAN" : "IDHACK";
assert.eq({_id: 2, a: 2}, coll.findAndModify({query: {_id: 2}, update: {$inc: {b: 1}}}));
profileObj = getLatestProfilerEntry(testDB);
diff --git a/jstests/core/timeseries/timeseries_bucket_index.js b/jstests/core/timeseries/timeseries_bucket_index.js
index e2bb2f78fea..3f864c35850 100644
--- a/jstests/core/timeseries/timeseries_bucket_index.js
+++ b/jstests/core/timeseries/timeseries_bucket_index.js
@@ -40,7 +40,7 @@ TimeseriesTest.run((insert) => {
assert.docEq(buckets, bucketsColl.find({_id: bucketId}).toArray());
let explain = bucketsColl.find({_id: bucketId}).explain();
- assert(planHasStage(db, explain, "COLLSCAN"), explain);
+ assert(planHasStage(db, explain, "CLUSTERED_IXSCAN"), explain);
assert.docEq(buckets, bucketsColl.find({"control.max.time": maxTime}).toArray());
explain = bucketsColl.find({"control.max.time": minTime}).explain();
diff --git a/jstests/core/timeseries/timeseries_id_range.js b/jstests/core/timeseries/timeseries_id_range.js
index 91ab77f87f1..13ab73d62fc 100644
--- a/jstests/core/timeseries/timeseries_id_range.js
+++ b/jstests/core/timeseries/timeseries_id_range.js
@@ -54,8 +54,8 @@ TimeseriesTest.run((insert) => {
}
}));
- assert(dates[5], getPlanStage(expl, "COLLSCAN").minRecord);
- assert(dates[5], getPlanStage(expl, "COLLSCAN").maxRecord);
+ assert(dates[5], getPlanStage(expl, "CLUSTERED_IXSCAN").minRecord);
+ assert(dates[5], getPlanStage(expl, "CLUSTERED_IXSCAN").maxRecord);
})();
(function testLTE() {
@@ -66,8 +66,8 @@ TimeseriesTest.run((insert) => {
assert.eq(0, res.length);
let expl = coll.explain("executionStats").aggregate(pipeline);
- assert(getAggPlanStage(expl, "COLLSCAN"), expl);
- assert(getAggPlanStage(expl, "COLLSCAN").hasOwnProperty("maxRecord"), expl);
+ assert(getAggPlanStage(expl, "CLUSTERED_IXSCAN"), expl);
+ assert(getAggPlanStage(expl, "CLUSTERED_IXSCAN").hasOwnProperty("maxRecord"), expl);
assert.eq(0, expl.stages[0].$cursor.executionStats.executionStages.nReturned);
for (let i = 0; i < dates.length; i++) {
@@ -88,7 +88,7 @@ TimeseriesTest.run((insert) => {
assert.eq(0, res.length);
let expl = coll.explain("executionStats").aggregate(pipeline);
- assert(getAggPlanStage(expl, "COLLSCAN").hasOwnProperty("maxRecord"));
+ assert(getAggPlanStage(expl, "CLUSTERED_IXSCAN").hasOwnProperty("maxRecord"));
assert.eq(0, expl.stages[0].$cursor.executionStats.executionStages.nReturned);
for (let i = 0; i < dates.length; i++) {
@@ -109,7 +109,7 @@ TimeseriesTest.run((insert) => {
assert.eq(0, res.length);
let expl = coll.explain("executionStats").aggregate(pipeline);
- assert(getAggPlanStage(expl, "COLLSCAN").hasOwnProperty("minRecord"));
+ assert(getAggPlanStage(expl, "CLUSTERED_IXSCAN").hasOwnProperty("minRecord"));
assert.eq(0, expl.stages[0].$cursor.executionStats.executionStages.nReturned);
for (let i = 0; i < dates.length; i++) {
@@ -130,7 +130,7 @@ TimeseriesTest.run((insert) => {
assert.eq(0, res.length);
let expl = coll.explain("executionStats").aggregate(pipeline);
- assert(getAggPlanStage(expl, "COLLSCAN").hasOwnProperty("minRecord"));
+ assert(getAggPlanStage(expl, "CLUSTERED_IXSCAN").hasOwnProperty("minRecord"));
assert.eq(0, expl.stages[0].$cursor.executionStats.executionStages.nReturned);
for (let i = 0; i < dates.length; i++) {
@@ -152,8 +152,8 @@ TimeseriesTest.run((insert) => {
assert.eq(0, res.length);
let expl = coll.explain("executionStats").aggregate(pipeline);
- assert(getAggPlanStage(expl, "COLLSCAN").hasOwnProperty("minRecord"));
- assert(getAggPlanStage(expl, "COLLSCAN").hasOwnProperty("maxRecord"));
+ assert(getAggPlanStage(expl, "CLUSTERED_IXSCAN").hasOwnProperty("minRecord"));
+ assert(getAggPlanStage(expl, "CLUSTERED_IXSCAN").hasOwnProperty("maxRecord"));
assert.eq(0, expl.stages[0].$cursor.executionStats.executionStages.nReturned);
for (let i = 0; i < dates.length; i++) {
@@ -175,8 +175,8 @@ TimeseriesTest.run((insert) => {
assert.eq(0, res.length);
let expl = coll.explain("executionStats").aggregate(pipeline);
- assert(getAggPlanStage(expl, "COLLSCAN").hasOwnProperty("minRecord"));
- assert(getAggPlanStage(expl, "COLLSCAN").hasOwnProperty("maxRecord"));
+ assert(getAggPlanStage(expl, "CLUSTERED_IXSCAN").hasOwnProperty("minRecord"));
+ assert(getAggPlanStage(expl, "CLUSTERED_IXSCAN").hasOwnProperty("maxRecord"));
assert.eq(0, expl.stages[0].$cursor.executionStats.executionStages.nReturned);
for (let i = 0; i < dates.length; i++) {
@@ -198,8 +198,8 @@ TimeseriesTest.run((insert) => {
assert.eq(0, res.length);
let expl = coll.explain("executionStats").aggregate(pipeline);
- assert(getAggPlanStage(expl, "COLLSCAN").hasOwnProperty("minRecord"));
- assert(getAggPlanStage(expl, "COLLSCAN").hasOwnProperty("maxRecord"));
+ assert(getAggPlanStage(expl, "CLUSTERED_IXSCAN").hasOwnProperty("minRecord"));
+ assert(getAggPlanStage(expl, "CLUSTERED_IXSCAN").hasOwnProperty("maxRecord"));
assert.eq(0, expl.stages[0].$cursor.executionStats.executionStages.nReturned);
for (let i = 0; i < dates.length; i++) {
@@ -221,8 +221,8 @@ TimeseriesTest.run((insert) => {
assert.eq(0, res.length);
let expl = coll.explain("executionStats").aggregate(pipeline);
- assert(getAggPlanStage(expl, "COLLSCAN").hasOwnProperty("minRecord"));
- assert(getAggPlanStage(expl, "COLLSCAN").hasOwnProperty("maxRecord"));
+ assert(getAggPlanStage(expl, "CLUSTERED_IXSCAN").hasOwnProperty("minRecord"));
+ assert(getAggPlanStage(expl, "CLUSTERED_IXSCAN").hasOwnProperty("maxRecord"));
assert.eq(0, expl.stages[0].$cursor.executionStats.executionStages.nReturned);
for (let i = 0; i < dates.length; i++) {
diff --git a/jstests/libs/analyze_plan.js b/jstests/libs/analyze_plan.js
index e03cfab5cae..24624c5ad59 100644
--- a/jstests/libs/analyze_plan.js
+++ b/jstests/libs/analyze_plan.js
@@ -367,6 +367,10 @@ function isCollscan(db, root) {
return planHasStage(db, root, "COLLSCAN");
}
+function isClusteredIxscan(db, root) {
+ return planHasStage(db, root, "CLUSTERED_IXSCAN");
+}
+
/**
* Returns true if the BSON representation of a plan rooted at 'root' is using the aggregation
* framework, and false otherwise.
diff --git a/jstests/libs/clustered_collections/clustered_collection_bounded_scan_common.js b/jstests/libs/clustered_collections/clustered_collection_bounded_scan_common.js
index 6a47a8d2f3c..3d8f46e0319 100644
--- a/jstests/libs/clustered_collections/clustered_collection_bounded_scan_common.js
+++ b/jstests/libs/clustered_collections/clustered_collection_bounded_scan_common.js
@@ -31,9 +31,9 @@ const testClusteredCollectionBoundedScan = function(coll, clusterKey) {
verbosity: "executionStats"
}));
- assert(getPlanStage(expl, "COLLSCAN"));
- assert.eq(5, getPlanStage(expl, "COLLSCAN").minRecord);
- assert.eq(5, getPlanStage(expl, "COLLSCAN").maxRecord);
+ assert(getPlanStage(expl, "CLUSTERED_IXSCAN"));
+ assert.eq(5, getPlanStage(expl, "CLUSTERED_IXSCAN").minRecord);
+ assert.eq(5, getPlanStage(expl, "CLUSTERED_IXSCAN").maxRecord);
assert.eq(1, expl.executionStats.executionStages.nReturned);
// Expect nReturned + 1 documents examined by design - additional cursor 'next' beyond
@@ -48,10 +48,10 @@ const testClusteredCollectionBoundedScan = function(coll, clusterKey) {
verbosity: "executionStats"
}));
- assert(getPlanStage(expl, "COLLSCAN"));
- assert(getPlanStage(expl, "COLLSCAN").hasOwnProperty("maxRecord"));
- assert(!getPlanStage(expl, "COLLSCAN").hasOwnProperty("minRecord"));
- assert.eq(10, getPlanStage(expl, "COLLSCAN").maxRecord);
+ assert(getPlanStage(expl, "CLUSTERED_IXSCAN"));
+ assert(getPlanStage(expl, "CLUSTERED_IXSCAN").hasOwnProperty("maxRecord"));
+ assert(!getPlanStage(expl, "CLUSTERED_IXSCAN").hasOwnProperty("minRecord"));
+ assert.eq(10, getPlanStage(expl, "CLUSTERED_IXSCAN").maxRecord);
assert.eq(expectedNReturned, expl.executionStats.executionStages.nReturned);
assert.eq(expectedDocsExamined, expl.executionStats.executionStages.docsExamined);
@@ -64,10 +64,10 @@ const testClusteredCollectionBoundedScan = function(coll, clusterKey) {
verbosity: "executionStats"
}));
- assert(getPlanStage(expl, "COLLSCAN"));
- assert(!getPlanStage(expl, "COLLSCAN").hasOwnProperty("maxRecord"));
- assert(getPlanStage(expl, "COLLSCAN").hasOwnProperty("minRecord"));
- assert.eq(89, getPlanStage(expl, "COLLSCAN").minRecord);
+ assert(getPlanStage(expl, "CLUSTERED_IXSCAN"));
+ assert(!getPlanStage(expl, "CLUSTERED_IXSCAN").hasOwnProperty("maxRecord"));
+ assert(getPlanStage(expl, "CLUSTERED_IXSCAN").hasOwnProperty("minRecord"));
+ assert.eq(89, getPlanStage(expl, "CLUSTERED_IXSCAN").minRecord);
assert.eq(expectedNReturned, expl.executionStats.executionStages.nReturned);
assert.eq(expectedDocsExamined, expl.executionStats.executionStages.docsExamined);
@@ -83,11 +83,11 @@ const testClusteredCollectionBoundedScan = function(coll, clusterKey) {
verbosity: "executionStats"
}));
- assert(getPlanStage(expl, "COLLSCAN"));
- assert(getPlanStage(expl, "COLLSCAN").hasOwnProperty("maxRecord"));
- assert(getPlanStage(expl, "COLLSCAN").hasOwnProperty("minRecord"));
- assert.eq(minVal, getPlanStage(expl, "COLLSCAN").minRecord);
- assert.eq(maxVal, getPlanStage(expl, "COLLSCAN").maxRecord);
+ assert(getPlanStage(expl, "CLUSTERED_IXSCAN"));
+ assert(getPlanStage(expl, "CLUSTERED_IXSCAN").hasOwnProperty("maxRecord"));
+ assert(getPlanStage(expl, "CLUSTERED_IXSCAN").hasOwnProperty("minRecord"));
+ assert.eq(minVal, getPlanStage(expl, "CLUSTERED_IXSCAN").minRecord);
+ assert.eq(maxVal, getPlanStage(expl, "CLUSTERED_IXSCAN").maxRecord);
assert.eq(expectedNReturned, expl.executionStats.executionStages.nReturned);
assert.eq(expectedDocsExamined, expl.executionStats.executionStages.docsExamined);
diff --git a/jstests/libs/clustered_collections/clustered_collection_hint_common.js b/jstests/libs/clustered_collections/clustered_collection_hint_common.js
index 6be6a4f4314..16123c75816 100644
--- a/jstests/libs/clustered_collections/clustered_collection_hint_common.js
+++ b/jstests/libs/clustered_collections/clustered_collection_hint_common.js
@@ -89,7 +89,7 @@ function testClusteredCollectionHint(coll, clusterKey, clusterKeyName) {
hint: clusterKey,
},
expectedWinningPlanStats: {
- stage: "COLLSCAN",
+ stage: "CLUSTERED_IXSCAN",
direction: "forward",
minRecord: arbitraryDocId,
maxRecord: arbitraryDocId
@@ -104,7 +104,7 @@ function testClusteredCollectionHint(coll, clusterKey, clusterKeyName) {
max: {[clusterKeyFieldName]: MaxKey}
},
expectedWinningPlanStats:
- {stage: "COLLSCAN", direction: "forward", minRecord: 101, maxRecord: MaxKey}
+ {stage: "CLUSTERED_IXSCAN", direction: "forward", minRecord: 101, maxRecord: MaxKey}
});
validateClusteredCollectionHint(coll, {
expectedNReturned: 0,
@@ -115,7 +115,7 @@ function testClusteredCollectionHint(coll, clusterKey, clusterKeyName) {
max: {[clusterKeyFieldName]: -2}
},
expectedWinningPlanStats:
- {stage: "COLLSCAN", direction: "forward", minRecord: MinKey, maxRecord: -2}
+ {stage: "CLUSTERED_IXSCAN", direction: "forward", minRecord: MinKey, maxRecord: -2}
});
validateClusteredCollectionHint(coll, {
expectedNReturned: 1,
@@ -125,7 +125,7 @@ function testClusteredCollectionHint(coll, clusterKey, clusterKeyName) {
hint: clusterKeyName,
},
expectedWinningPlanStats: {
- stage: "COLLSCAN",
+ stage: "CLUSTERED_IXSCAN",
direction: "forward",
minRecord: arbitraryDocId,
maxRecord: arbitraryDocId
@@ -139,7 +139,7 @@ function testClusteredCollectionHint(coll, clusterKey, clusterKeyName) {
hint: clusterKey,
},
expectedWinningPlanStats:
- {stage: "COLLSCAN", direction: "forward", maxRecord: arbitraryDocId}
+ {stage: "CLUSTERED_IXSCAN", direction: "forward", maxRecord: arbitraryDocId}
});
validateClusteredCollectionHint(coll, {
expectedNReturned: batchSize - arbitraryDocId,
@@ -149,7 +149,7 @@ function testClusteredCollectionHint(coll, clusterKey, clusterKeyName) {
hint: clusterKey,
},
expectedWinningPlanStats:
- {stage: "COLLSCAN", direction: "forward", minRecord: arbitraryDocId}
+ {stage: "CLUSTERED_IXSCAN", direction: "forward", minRecord: arbitraryDocId}
});
// Find with $natural hints.
@@ -206,7 +206,7 @@ function testClusteredCollectionHint(coll, clusterKey, clusterKeyName) {
updates: [{q: {[clusterKeyFieldName]: 3}, u: {$inc: {a: -2}}, hint: clusterKey}]
},
expectedWinningPlanStats:
- {stage: "COLLSCAN", direction: "forward", minRecord: 3, maxRecord: 3}
+ {stage: "CLUSTERED_IXSCAN", direction: "forward", minRecord: 3, maxRecord: 3}
});
// Update with reverse $natural hint.
@@ -218,7 +218,7 @@ function testClusteredCollectionHint(coll, clusterKey, clusterKeyName) {
[{q: {[clusterKeyFieldName]: 80}, u: {$inc: {a: 80}}, hint: {$natural: -1}}]
},
expectedWinningPlanStats:
- {stage: "COLLSCAN", direction: "backward", minRecord: 80, maxRecord: 80}
+ {stage: "CLUSTERED_IXSCAN", direction: "backward", minRecord: 80, maxRecord: 80}
});
// Update with hint on secondary index.
@@ -239,7 +239,7 @@ function testClusteredCollectionHint(coll, clusterKey, clusterKeyName) {
deletes: [{q: {[clusterKeyFieldName]: 2}, limit: 0, hint: clusterKey}]
},
expectedWinningPlanStats:
- {stage: "COLLSCAN", direction: "forward", minRecord: 2, maxRecord: 2}
+ {stage: "CLUSTERED_IXSCAN", direction: "forward", minRecord: 2, maxRecord: 2}
});
// Delete reverse $natural hint.
@@ -250,7 +250,7 @@ function testClusteredCollectionHint(coll, clusterKey, clusterKeyName) {
deletes: [{q: {[clusterKeyFieldName]: 30}, limit: 0, hint: {$natural: -1}}]
},
expectedWinningPlanStats:
- {stage: "COLLSCAN", direction: "backward", minRecord: 30, maxRecord: 30}
+ {stage: "CLUSTERED_IXSCAN", direction: "backward", minRecord: 30, maxRecord: 30}
});
// Delete with hint on standard index.
diff --git a/src/mongo/db/exec/collection_scan.cpp b/src/mongo/db/exec/collection_scan.cpp
index c6a4690080f..cb8e776eaec 100644
--- a/src/mongo/db/exec/collection_scan.cpp
+++ b/src/mongo/db/exec/collection_scan.cpp
@@ -51,8 +51,13 @@ namespace mongo {
using std::unique_ptr;
using std::vector;
-// static
-const char* CollectionScan::kStageType = "COLLSCAN";
+namespace {
+const char* getStageName(const CollectionPtr& coll, const CollectionScanParams& params) {
+ return (!coll->ns().isOplog() && (params.minRecord || params.maxRecord)) ? "CLUSTERED_IXSCAN"
+ : "COLLSCAN";
+}
+} // namespace
+
CollectionScan::CollectionScan(ExpressionContext* expCtx,
const CollectionPtr& collection,
@@ -60,7 +65,8 @@ CollectionScan::CollectionScan(ExpressionContext* expCtx,
WorkingSet* workingSet,
const MatchExpression* filter,
bool relaxCappedConstraints)
- : RequiresCollectionStage(kStageType, expCtx, collection, relaxCappedConstraints),
+ : RequiresCollectionStage(
+ getStageName(collection, params), expCtx, collection, relaxCappedConstraints),
_workingSet(workingSet),
_filter((filter && !filter->isTriviallyTrue()) ? filter : nullptr),
_params(params) {
diff --git a/src/mongo/db/exec/collection_scan.h b/src/mongo/db/exec/collection_scan.h
index 69d71cc70b1..0ddb2f9e348 100644
--- a/src/mongo/db/exec/collection_scan.h
+++ b/src/mongo/db/exec/collection_scan.h
@@ -52,8 +52,6 @@ class OperationContext;
*/
class CollectionScan final : public RequiresCollectionStage {
public:
- static const char* kStageType;
-
CollectionScan(ExpressionContext* expCtx,
const CollectionPtr& collection,
const CollectionScanParams& params,