summaryrefslogtreecommitdiff
path: root/jstests/aggregation/bugs/match.js
diff options
context:
space:
mode:
Diffstat (limited to 'jstests/aggregation/bugs/match.js')
-rw-r--r--jstests/aggregation/bugs/match.js321
1 files changed, 162 insertions, 159 deletions
diff --git a/jstests/aggregation/bugs/match.js b/jstests/aggregation/bugs/match.js
index 8cb4519a861..6a545ed60c1 100644
--- a/jstests/aggregation/bugs/match.js
+++ b/jstests/aggregation/bugs/match.js
@@ -2,166 +2,169 @@
// - Filtering behavior equivalent to a mongo query.
// - $where and geo operators are not allowed
(function() {
- "use strict";
-
- load('jstests/aggregation/extras/utils.js');
-
- const coll = db.jstests_aggregation_match;
- coll.drop();
-
- const identityProjection = {_id: '$_id', a: '$a'};
-
- /** Assert that an aggregation generated the expected error. */
- function assertError(expectedCode, matchSpec) {
- const matchStage = {$match: matchSpec};
- // Check where matching is folded in to DocumentSourceCursor.
- assertErrorCode(coll, [matchStage], expectedCode);
- // Check where matching is not folded in to DocumentSourceCursor.
- assertErrorCode(coll, [{$project: identityProjection}, matchStage], expectedCode);
+"use strict";
+
+load('jstests/aggregation/extras/utils.js');
+
+const coll = db.jstests_aggregation_match;
+coll.drop();
+
+const identityProjection = {
+ _id: '$_id',
+ a: '$a'
+};
+
+/** Assert that an aggregation generated the expected error. */
+function assertError(expectedCode, matchSpec) {
+ const matchStage = {$match: matchSpec};
+ // Check where matching is folded in to DocumentSourceCursor.
+ assertErrorCode(coll, [matchStage], expectedCode);
+ // Check where matching is not folded in to DocumentSourceCursor.
+ assertErrorCode(coll, [{$project: identityProjection}, matchStage], expectedCode);
+}
+
+/** Assert that the contents of two arrays are equal, ignoring element ordering. */
+function assertEqualResultsUnordered(one, two) {
+ let oneStr = one.map(function(x) {
+ return tojson(x);
+ });
+ let twoStr = two.map(function(x) {
+ return tojson(x);
+ });
+ oneStr.sort();
+ twoStr.sort();
+ assert.eq(oneStr, twoStr);
+}
+
+/** Assert that an aggregation result is as expected. */
+function assertResults(expectedResults, matchSpec) {
+ const findResults = coll.find(matchSpec).toArray();
+ if (expectedResults) {
+ assertEqualResultsUnordered(expectedResults, findResults);
}
-
- /** Assert that the contents of two arrays are equal, ignoring element ordering. */
- function assertEqualResultsUnordered(one, two) {
- let oneStr = one.map(function(x) {
- return tojson(x);
- });
- let twoStr = two.map(function(x) {
- return tojson(x);
- });
- oneStr.sort();
- twoStr.sort();
- assert.eq(oneStr, twoStr);
- }
-
- /** Assert that an aggregation result is as expected. */
- function assertResults(expectedResults, matchSpec) {
- const findResults = coll.find(matchSpec).toArray();
- if (expectedResults) {
- assertEqualResultsUnordered(expectedResults, findResults);
- }
- const matchStage = {$match: matchSpec};
- // Check where matching is folded in to DocumentSourceCursor.
- assertEqualResultsUnordered(findResults, coll.aggregate(matchStage).toArray());
- // Check where matching is not folded in to DocumentSourceCursor.
- assertEqualResultsUnordered(
- findResults, coll.aggregate({$project: identityProjection}, matchStage).toArray());
- }
-
- // Invalid matcher syntax.
- assertError(2, {a: {$mod: [0 /* invalid */, 0]}});
-
- // $where not allowed.
- assertError(ErrorCodes.BadValue, {$where: 'true'});
-
- // Geo not allowed.
- assertError(ErrorCodes.BadValue, {$match: {a: {$near: [0, 0]}}});
-
- function checkMatchResults(indexed) {
- // No results.
- coll.remove({});
- assertResults([], {});
-
- assert.writeOK(coll.insert({_id: 0, a: 1}));
- assert.writeOK(coll.insert({_id: 1, a: 2}));
- assert.writeOK(coll.insert({_id: 2, a: 3}));
-
- // Empty query.
- assertResults([{_id: 0, a: 1}, {_id: 1, a: 2}, {_id: 2, a: 3}], {});
-
- // Simple queries.
- assertResults([{_id: 0, a: 1}], {a: 1});
- assertResults([{_id: 1, a: 2}], {a: 2});
- assertResults([{_id: 1, a: 2}, {_id: 2, a: 3}], {a: {$gt: 1}});
- assertResults([{_id: 0, a: 1}, {_id: 1, a: 2}], {a: {$lte: 2}});
- assertResults([{_id: 0, a: 1}, {_id: 2, a: 3}], {a: {$in: [1, 3]}});
-
- // Regular expression.
- coll.remove({});
- assert.writeOK(coll.insert({_id: 0, a: 'x'}));
- assert.writeOK(coll.insert({_id: 1, a: 'yx'}));
- assertResults([{_id: 0, a: 'x'}], {a: /^x/});
- assertResults([{_id: 0, a: 'x'}, {_id: 1, a: 'yx'}], {a: /x/});
-
- // Dotted field.
- coll.remove({});
- assert.writeOK(coll.insert({_id: 0, a: {b: 4}}));
- assert.writeOK(coll.insert({_id: 1, a: 2}));
- assertResults([{_id: 0, a: {b: 4}}], {'a.b': 4});
-
- // Value within an array.
- coll.remove({});
- assert.writeOK(coll.insert({_id: 0, a: [1, 2, 3]}));
- assert.writeOK(coll.insert({_id: 1, a: [2, 2, 3]}));
- assert.writeOK(coll.insert({_id: 2, a: [2, 2, 2]}));
- assertResults([{_id: 0, a: [1, 2, 3]}, {_id: 1, a: [2, 2, 3]}], {a: 3});
-
- // Missing, null, $exists matching.
- coll.remove({});
- assert.writeOK(coll.insert({_id: 0}));
- assert.writeOK(coll.insert({_id: 1, a: null}));
- assert.writeOK(coll.insert({_id: 3, a: 0}));
- assertResults([{_id: 0}, {_id: 1, a: null}], {a: null});
- assertResults(null, {a: {$exists: true}});
- assertResults(null, {a: {$exists: false}});
-
- // $elemMatch
- coll.remove({});
- assert.writeOK(coll.insert({_id: 0, a: [1, 2]}));
- assert.writeOK(coll.insert({_id: 1, a: [1, 2, 3]}));
- assertResults([{_id: 1, a: [1, 2, 3]}], {a: {$elemMatch: {$gt: 1, $mod: [2, 1]}}});
-
- coll.remove({});
- assert.writeOK(coll.insert({_id: 0, a: [{b: 1}, {c: 2}]}));
- assert.writeOK(coll.insert({_id: 1, a: [{b: 1, c: 2}]}));
- assertResults([{_id: 1, a: [{b: 1, c: 2}]}], {a: {$elemMatch: {b: 1, c: 2}}});
-
- // $size
- coll.remove({});
- assert.writeOK(coll.insert({}));
- assert.writeOK(coll.insert({a: null}));
- assert.writeOK(coll.insert({a: []}));
- assert.writeOK(coll.insert({a: [1]}));
- assert.writeOK(coll.insert({a: [1, 2]}));
- assertResults(null, {a: {$size: 0}});
- assertResults(null, {a: {$size: 1}});
- assertResults(null, {a: {$size: 2}});
-
- // $type
- coll.remove({});
- assert.writeOK(coll.insert({}));
- assert.writeOK(coll.insert({a: null}));
- assert.writeOK(coll.insert({a: NumberInt(1)}));
- assert.writeOK(coll.insert({a: NumberLong(2)}));
- assert.writeOK(coll.insert({a: 66.6}));
- assert.writeOK(coll.insert({a: 'abc'}));
- assert.writeOK(coll.insert({a: /xyz/}));
- assert.writeOK(coll.insert({a: {q: 1}}));
- assert.writeOK(coll.insert({a: true}));
- assert.writeOK(coll.insert({a: new Date()}));
- assert.writeOK(coll.insert({a: new ObjectId()}));
- for (let type = 1; type <= 18; ++type) {
- assertResults(null, {a: {$type: type}});
- }
-
- coll.remove({});
- assert.writeOK(coll.insert({_id: 0, a: 1}));
- assert.writeOK(coll.insert({_id: 1, a: 2}));
- assert.writeOK(coll.insert({_id: 2, a: 3}));
-
- // $and
- assertResults([{_id: 1, a: 2}], {$and: [{a: 2}, {_id: 1}]});
- assertResults([], {$and: [{a: 1}, {_id: 1}]});
- assertResults([{_id: 1, a: 2}, {_id: 2, a: 3}],
- {$and: [{$or: [{_id: 1}, {a: 3}]}, {$or: [{_id: 2}, {a: 2}]}]});
-
- // $or
- assertResults([{_id: 0, a: 1}, {_id: 2, a: 3}], {$or: [{_id: 0}, {a: 3}]});
+ const matchStage = {$match: matchSpec};
+ // Check where matching is folded in to DocumentSourceCursor.
+ assertEqualResultsUnordered(findResults, coll.aggregate(matchStage).toArray());
+ // Check where matching is not folded in to DocumentSourceCursor.
+ assertEqualResultsUnordered(
+ findResults, coll.aggregate({$project: identityProjection}, matchStage).toArray());
+}
+
+// Invalid matcher syntax.
+assertError(2, {a: {$mod: [0 /* invalid */, 0]}});
+
+// $where not allowed.
+assertError(ErrorCodes.BadValue, {$where: 'true'});
+
+// Geo not allowed.
+assertError(ErrorCodes.BadValue, {$match: {a: {$near: [0, 0]}}});
+
+function checkMatchResults(indexed) {
+ // No results.
+ coll.remove({});
+ assertResults([], {});
+
+ assert.writeOK(coll.insert({_id: 0, a: 1}));
+ assert.writeOK(coll.insert({_id: 1, a: 2}));
+ assert.writeOK(coll.insert({_id: 2, a: 3}));
+
+ // Empty query.
+ assertResults([{_id: 0, a: 1}, {_id: 1, a: 2}, {_id: 2, a: 3}], {});
+
+ // Simple queries.
+ assertResults([{_id: 0, a: 1}], {a: 1});
+ assertResults([{_id: 1, a: 2}], {a: 2});
+ assertResults([{_id: 1, a: 2}, {_id: 2, a: 3}], {a: {$gt: 1}});
+ assertResults([{_id: 0, a: 1}, {_id: 1, a: 2}], {a: {$lte: 2}});
+ assertResults([{_id: 0, a: 1}, {_id: 2, a: 3}], {a: {$in: [1, 3]}});
+
+ // Regular expression.
+ coll.remove({});
+ assert.writeOK(coll.insert({_id: 0, a: 'x'}));
+ assert.writeOK(coll.insert({_id: 1, a: 'yx'}));
+ assertResults([{_id: 0, a: 'x'}], {a: /^x/});
+ assertResults([{_id: 0, a: 'x'}, {_id: 1, a: 'yx'}], {a: /x/});
+
+ // Dotted field.
+ coll.remove({});
+ assert.writeOK(coll.insert({_id: 0, a: {b: 4}}));
+ assert.writeOK(coll.insert({_id: 1, a: 2}));
+ assertResults([{_id: 0, a: {b: 4}}], {'a.b': 4});
+
+ // Value within an array.
+ coll.remove({});
+ assert.writeOK(coll.insert({_id: 0, a: [1, 2, 3]}));
+ assert.writeOK(coll.insert({_id: 1, a: [2, 2, 3]}));
+ assert.writeOK(coll.insert({_id: 2, a: [2, 2, 2]}));
+ assertResults([{_id: 0, a: [1, 2, 3]}, {_id: 1, a: [2, 2, 3]}], {a: 3});
+
+ // Missing, null, $exists matching.
+ coll.remove({});
+ assert.writeOK(coll.insert({_id: 0}));
+ assert.writeOK(coll.insert({_id: 1, a: null}));
+ assert.writeOK(coll.insert({_id: 3, a: 0}));
+ assertResults([{_id: 0}, {_id: 1, a: null}], {a: null});
+ assertResults(null, {a: {$exists: true}});
+ assertResults(null, {a: {$exists: false}});
+
+ // $elemMatch
+ coll.remove({});
+ assert.writeOK(coll.insert({_id: 0, a: [1, 2]}));
+ assert.writeOK(coll.insert({_id: 1, a: [1, 2, 3]}));
+ assertResults([{_id: 1, a: [1, 2, 3]}], {a: {$elemMatch: {$gt: 1, $mod: [2, 1]}}});
+
+ coll.remove({});
+ assert.writeOK(coll.insert({_id: 0, a: [{b: 1}, {c: 2}]}));
+ assert.writeOK(coll.insert({_id: 1, a: [{b: 1, c: 2}]}));
+ assertResults([{_id: 1, a: [{b: 1, c: 2}]}], {a: {$elemMatch: {b: 1, c: 2}}});
+
+ // $size
+ coll.remove({});
+ assert.writeOK(coll.insert({}));
+ assert.writeOK(coll.insert({a: null}));
+ assert.writeOK(coll.insert({a: []}));
+ assert.writeOK(coll.insert({a: [1]}));
+ assert.writeOK(coll.insert({a: [1, 2]}));
+ assertResults(null, {a: {$size: 0}});
+ assertResults(null, {a: {$size: 1}});
+ assertResults(null, {a: {$size: 2}});
+
+ // $type
+ coll.remove({});
+ assert.writeOK(coll.insert({}));
+ assert.writeOK(coll.insert({a: null}));
+ assert.writeOK(coll.insert({a: NumberInt(1)}));
+ assert.writeOK(coll.insert({a: NumberLong(2)}));
+ assert.writeOK(coll.insert({a: 66.6}));
+ assert.writeOK(coll.insert({a: 'abc'}));
+ assert.writeOK(coll.insert({a: /xyz/}));
+ assert.writeOK(coll.insert({a: {q: 1}}));
+ assert.writeOK(coll.insert({a: true}));
+ assert.writeOK(coll.insert({a: new Date()}));
+ assert.writeOK(coll.insert({a: new ObjectId()}));
+ for (let type = 1; type <= 18; ++type) {
+ assertResults(null, {a: {$type: type}});
}
- checkMatchResults(false);
- coll.createIndex({a: 1});
- checkMatchResults(true);
- coll.createIndex({'a.b': 1});
- coll.createIndex({'a.c': 1});
- checkMatchResults(true);
+ coll.remove({});
+ assert.writeOK(coll.insert({_id: 0, a: 1}));
+ assert.writeOK(coll.insert({_id: 1, a: 2}));
+ assert.writeOK(coll.insert({_id: 2, a: 3}));
+
+ // $and
+ assertResults([{_id: 1, a: 2}], {$and: [{a: 2}, {_id: 1}]});
+ assertResults([], {$and: [{a: 1}, {_id: 1}]});
+ assertResults([{_id: 1, a: 2}, {_id: 2, a: 3}],
+ {$and: [{$or: [{_id: 1}, {a: 3}]}, {$or: [{_id: 2}, {a: 2}]}]});
+
+ // $or
+ assertResults([{_id: 0, a: 1}, {_id: 2, a: 3}], {$or: [{_id: 0}, {a: 3}]});
+}
+
+checkMatchResults(false);
+coll.createIndex({a: 1});
+checkMatchResults(true);
+coll.createIndex({'a.b': 1});
+coll.createIndex({'a.c': 1});
+checkMatchResults(true);
})();