summaryrefslogtreecommitdiff
path: root/jstests/core
diff options
context:
space:
mode:
authorIan Boros <puppyofkosh@gmail.com>2019-02-22 19:17:37 -0500
committerIan Boros <puppyofkosh@gmail.com>2019-02-22 19:19:33 -0500
commit4253bddd476f19fb6af295323acc9d5af15da598 (patch)
tree59208de80aa28fee01956af649c6fc34ff1d3864 /jstests/core
parentbe68e9b78da63075c9b82304ea27ae4725fe894c (diff)
downloadmongo-4253bddd476f19fb6af295323acc9d5af15da598.tar.gz
SERVER-39470 Modernize arrayfind8.js
Diffstat (limited to 'jstests/core')
-rw-r--r--jstests/core/arrayfind8.js281
1 files changed, 133 insertions, 148 deletions
diff --git a/jstests/core/arrayfind8.js b/jstests/core/arrayfind8.js
index a687351b554..f9693182a7a 100644
--- a/jstests/core/arrayfind8.js
+++ b/jstests/core/arrayfind8.js
@@ -1,163 +1,148 @@
-// Matching behavior for $elemMatch applied to a top level element.
-// SERVER-1264
-// SERVER-4180
-var debuggingEnabled = false;
-
-t = db.jstests_arrayfind8;
-t.drop();
-
-function debug(x) {
- if (debuggingEnabled) {
- printjson(x);
+/**
+ * Matching behavior for $elemMatch applied to a top level element.
+ * Includes tests for bugs described in SERVER-1264 and SERVER-4180.
+ */
+(function() {
+ "use strict";
+
+ const coll = db.jstests_arrayfind8;
+ coll.drop();
+
+ // May be changed during the test.
+ let currentIndexSpec = {a: 1};
+
+ /**
+ * Check that the query results match the documents in the 'expected' array.
+ */
+ function assertResults(expected, query, context) {
+ assert.eq(expected.length, coll.count(query), 'unexpected count in ' + context);
+ const results = coll.find(query).toArray();
+ const resultsAOnly = results.map((r) => r.a);
+ assert.sameMembers(resultsAOnly, expected);
}
-}
-
-/** Set index state for the test. */
-function setIndexKey(key) {
- indexKey = key;
- indexSpec = {};
- indexSpec[key] = 1;
-}
-
-setIndexKey('a');
-
-/** Check that the query results match the documents in the 'expected' array. */
-function assertResults(expected, query, context) {
- debug(query);
- assert.eq(expected.length, t.count(query), 'unexpected count in ' + context);
- results = t.find(query).toArray();
- for (i in results) {
- found = false;
- for (j in expected) {
- if (friendlyEqual(expected[j], results[i].a)) {
- found = true;
+
+ /**
+ * Check matching for different query types.
+ * @param bothMatch - document matched by both standardQuery and elemMatchQuery
+ * @param elemMatch - document matched by elemMatchQuery but not standardQuery
+ * @param notElemMatch - document matched by standardQuery but not elemMatchQuery
+ */
+ function checkMatch(
+ bothMatch, elemMatch, nonElemMatch, standardQuery, elemMatchQuery, context) {
+ function mayPush(arr, elt) {
+ if (elt) {
+ arr.push(elt);
}
}
- assert(found, 'unexpected result ' + results[i] + ' in ' + context);
+
+ let expectedStandardQueryResults = [];
+ mayPush(expectedStandardQueryResults, bothMatch);
+ mayPush(expectedStandardQueryResults, nonElemMatch);
+ assertResults(expectedStandardQueryResults, standardQuery, context + ' standard query');
+
+ let expectedElemMatchQueryResults = [];
+ mayPush(expectedElemMatchQueryResults, bothMatch);
+ mayPush(expectedElemMatchQueryResults, elemMatch);
+ assertResults(expectedElemMatchQueryResults, elemMatchQuery, context + ' elemMatch query');
}
-}
-/**
- * Check matching for different query types.
- * @param bothMatch - document matched by both standardQuery and elemMatchQuery
- * @param elemMatch - document matched by elemMatchQuery but not standardQuery
- * @param notElemMatch - document matched by standardQuery but not elemMatchQuery
- */
-function checkMatch(bothMatch, elemMatch, nonElemMatch, standardQuery, elemMatchQuery, context) {
- function mayPush(arr, elt) {
- if (elt) {
- arr.push(elt);
+ /**
+ * Check matching and for different query types.
+ * @param subQuery - part of a query, to be provided as is for a standard query and within a
+ * $elemMatch clause for a $elemMatch query
+ * @param bothMatch - document matched by both standardQuery and elemMatchQuery
+ * @param elemMatch - document matched by elemMatchQuery but not standardQuery
+ * @param notElemMatch - document matched by standardQuery but not elemMatchQuery
+ * @param additionalConstraints - additional query parameters not generated from @param subQuery
+ */
+ function checkQuery(subQuery, bothMatch, elemMatch, nonElemMatch, additionalConstraints) {
+ coll.drop();
+ additionalConstraints = additionalConstraints || {};
+
+ // Construct standard and elemMatch queries from subQuery.
+ const firstSubQueryKey = Object.keySet(subQuery)[0];
+ let standardQuery = null;
+ if (firstSubQueryKey[0] == '$') {
+ standardQuery = {$and: [{a: subQuery}, additionalConstraints]};
+ } else {
+ // If the subQuery contains a field rather than operators, append to the 'a' field.
+ let modifiedSubQuery = {};
+ modifiedSubQuery['a.' + firstSubQueryKey] = subQuery[firstSubQueryKey];
+ standardQuery = {$and: [modifiedSubQuery, additionalConstraints]};
}
- }
+ const elemMatchQuery = {$and: [{a: {$elemMatch: subQuery}}, additionalConstraints]};
- expectedStandardQueryResults = [];
- mayPush(expectedStandardQueryResults, bothMatch);
- mayPush(expectedStandardQueryResults, nonElemMatch);
- assertResults(expectedStandardQueryResults, standardQuery, context + ' standard query');
+ function insertValueIfNotNull(val) {
+ if (val) {
+ assert.commandWorked(coll.insert({a: val}));
+ }
+ }
- expectedElemMatchQueryResults = [];
- mayPush(expectedElemMatchQueryResults, bothMatch);
- mayPush(expectedElemMatchQueryResults, elemMatch);
- assertResults(expectedElemMatchQueryResults, elemMatchQuery, context + ' elemMatch query');
-}
+ // Save all documents and check matching without indexes.
+ insertValueIfNotNull(bothMatch);
+ insertValueIfNotNull(elemMatch);
+ insertValueIfNotNull(nonElemMatch);
-/**
- * Check matching and for different query types.
- * @param subQuery - part of a query, to be provided as is for a standard query and within a
- * $elemMatch clause for a $elemMatch query
- * @param bothMatch - document matched by both standardQuery and elemMatchQuery
- * @param elemMatch - document matched by elemMatchQuery but not standardQuery
- * @param notElemMatch - document matched by standardQuery but not elemMatchQuery
- * @param additionalConstraints - additional query parameters not generated from @param subQuery
- */
-function checkQuery(subQuery, bothMatch, elemMatch, nonElemMatch, additionalConstraints) {
- t.drop();
- additionalConstraints = additionalConstraints || {};
-
- // Construct standard and elemMatch queries from subQuery.
- firstSubQueryKey = Object.keySet(subQuery)[0];
- if (firstSubQueryKey[0] == '$') {
- standardQuery = {$and: [{a: subQuery}, additionalConstraints]};
- } else {
- // If the subQuery contains a field rather than operators, append to the 'a' field.
- modifiedSubQuery = {};
- modifiedSubQuery['a.' + firstSubQueryKey] = subQuery[firstSubQueryKey];
- standardQuery = {$and: [modifiedSubQuery, additionalConstraints]};
- }
- elemMatchQuery = {$and: [{a: {$elemMatch: subQuery}}, additionalConstraints]};
- debug(elemMatchQuery);
+ checkMatch(bothMatch, elemMatch, nonElemMatch, standardQuery, elemMatchQuery, 'unindexed');
- function maySave(aValue) {
- if (aValue) {
- debug({a: aValue});
- t.save({a: aValue});
- }
+ // Check matching and index bounds for a single key index.
+
+ assert.eq(coll.drop(), true);
+ insertValueIfNotNull(bothMatch);
+ insertValueIfNotNull(elemMatch);
+ // The nonElemMatch document is not tested here, as it will often make the index multikey.
+ assert.commandWorked(coll.createIndex(currentIndexSpec));
+ checkMatch(bothMatch, elemMatch, null, standardQuery, elemMatchQuery, 'single key index');
+
+ // Check matching and index bounds for a multikey index.
+
+ // Now the nonElemMatch document is tested.
+ insertValueIfNotNull(nonElemMatch);
+ // Force the index to be multikey.
+ assert.commandWorked(coll.insert({a: [-1, -2]}));
+ assert.commandWorked(coll.insert({a: {b: [-1, -2]}}));
+ checkMatch(
+ bothMatch, elemMatch, nonElemMatch, standardQuery, elemMatchQuery, 'multikey index');
}
- // Save all documents and check matching without indexes.
- maySave(bothMatch);
- maySave(elemMatch);
- maySave(nonElemMatch);
-
- checkMatch(bothMatch, elemMatch, nonElemMatch, standardQuery, elemMatchQuery, 'unindexed');
-
- // Check matching and index bounds for a single key index.
-
- t.drop();
- maySave(bothMatch);
- maySave(elemMatch);
- // The nonElemMatch document is not tested here, as it will often make the index multikey.
- t.ensureIndex(indexSpec);
- checkMatch(bothMatch, elemMatch, null, standardQuery, elemMatchQuery, 'single key index');
-
- // Check matching and index bounds for a multikey index.
-
- // Now the nonElemMatch document is tested.
- maySave(nonElemMatch);
- // Force the index to be multikey.
- t.save({a: [-1, -2]});
- t.save({a: {b: [-1, -2]}});
- checkMatch(bothMatch, elemMatch, nonElemMatch, standardQuery, elemMatchQuery, 'multikey index');
-}
-
-maxNumber = Infinity;
-
-// Basic test.
-checkQuery({$gt: 4}, [5]);
-
-// Multiple constraints within a $elemMatch clause.
-checkQuery({$gt: 4, $lt: 6}, [5], null, [3, 7]);
-checkQuery({$gt: 4, $not: {$gte: 6}}, [5]);
-checkQuery({$gt: 4, $not: {$ne: 6}}, [6]);
-checkQuery({$gte: 5, $lte: 5}, [5], null, [4, 6]);
-checkQuery({$in: [4, 6], $gt: 5}, [6], null, [4, 7]);
-checkQuery({$regex: '^a'}, ['a']);
-
-// Some constraints within a $elemMatch clause and other constraints outside of it.
-checkQuery({$gt: 4}, [5], null, null, {a: {$lt: 6}});
-checkQuery({$gte: 5}, [5], null, null, {a: {$lte: 5}});
-checkQuery({$in: [4, 6]}, [6], null, null, {a: {$gt: 5}});
-
-// Constraints in different $elemMatch clauses.
-checkQuery({$gt: 4}, [5], null, null, {a: {$elemMatch: {$lt: 6}}});
-checkQuery({$gt: 4}, [3, 7], null, null, {a: {$elemMatch: {$lt: 6}}});
-checkQuery({$gte: 5}, [5], null, null, {a: {$elemMatch: {$lte: 5}}});
-checkQuery({$in: [4, 6]}, [6], null, null, {a: {$elemMatch: {$gt: 5}}});
-
-// TODO SERVER-1264
-if (0) {
- checkQuery({$elemMatch: {$in: [5]}}, null, [[5]], [5], null);
-}
+ // Basic test.
+ checkQuery({$gt: 4}, [5]);
+
+ // Multiple constraints within a $elemMatch clause.
+ checkQuery({$gt: 4, $lt: 6}, [5], null, [3, 7]);
+ checkQuery({$gt: 4, $not: {$gte: 6}}, [5]);
+ checkQuery({$gt: 4, $not: {$ne: 6}}, [6]);
+ checkQuery({$gte: 5, $lte: 5}, [5], null, [4, 6]);
+ checkQuery({$in: [4, 6], $gt: 5}, [6], null, [4, 7]);
+ checkQuery({$regex: '^a'}, ['a']);
-setIndexKey('a.b');
-checkQuery({$elemMatch: {b: {$gte: 1, $lte: 1}}}, null, [[{b: 1}]], [{b: 1}], null);
-checkQuery({$elemMatch: {b: {$gte: 1, $lte: 1}}}, null, [[{b: [0, 2]}]], [{b: [0, 2]}], null);
+ // Some constraints within a $elemMatch clause and other constraints outside of it.
+ checkQuery({$gt: 4}, [5], null, null, {a: {$lt: 6}});
+ checkQuery({$gte: 5}, [5], null, null, {a: {$lte: 5}});
+ checkQuery({$in: [4, 6]}, [6], null, null, {a: {$gt: 5}});
-// Constraints for a top level (SERVER-1264 style) $elemMatch nested within a non top level
-// $elemMatch.
-checkQuery({b: {$elemMatch: {$gte: 1, $lte: 1}}}, [{b: [1]}]);
-checkQuery({b: {$elemMatch: {$gte: 1, $lte: 4}}}, [{b: [1]}]);
+ // Constraints in different $elemMatch clauses.
+ checkQuery({$gt: 4}, [5], null, null, {a: {$elemMatch: {$lt: 6}}});
+ checkQuery({$gt: 4}, [3, 7], null, null, {a: {$elemMatch: {$lt: 6}}});
+ checkQuery({$gte: 5}, [5], null, null, {a: {$elemMatch: {$lte: 5}}});
+ checkQuery({$in: [4, 6]}, [6], null, null, {a: {$elemMatch: {$gt: 5}}});
+
+ checkQuery({$elemMatch: {$in: [5]}}, null, [[5]], [5], null);
-checkQuery({b: {$elemMatch: {$gte: 1, $lte: 4}}}, [{b: [2]}], null, null, {'a.b': {$in: [2, 5]}});
-checkQuery(
- {b: {$elemMatch: {$in: [1, 2]}, $in: [2, 3]}}, [{b: [2]}], null, [{b: [1]}, {b: [3]}], null);
+ currentIndexSpec = {"a.b": 1};
+ checkQuery({$elemMatch: {b: {$gte: 1, $lte: 1}}}, null, [[{b: 1}]], [{b: 1}], null);
+ checkQuery({$elemMatch: {b: {$gte: 1, $lte: 1}}}, null, [[{b: [0, 2]}]], [{b: [0, 2]}], null);
+
+ // Constraints for a top level (SERVER-1264 style) $elemMatch nested within a non top level
+ // $elemMatch.
+ checkQuery({b: {$elemMatch: {$gte: 1, $lte: 1}}}, [{b: [1]}]);
+ checkQuery({b: {$elemMatch: {$gte: 1, $lte: 4}}}, [{b: [1]}]);
+
+ checkQuery(
+ {b: {$elemMatch: {$gte: 1, $lte: 4}}}, [{b: [2]}], null, null, {'a.b': {$in: [2, 5]}});
+ checkQuery({b: {$elemMatch: {$in: [1, 2]}, $in: [2, 3]}},
+ [{b: [2]}],
+ null,
+ [{b: [1]}, {b: [3]}],
+ null);
+})();