summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharlie Swanson <charlie.swanson@mongodb.com>2019-10-01 19:53:39 +0000
committerevergreen <evergreen@mongodb.com>2019-10-01 19:53:39 +0000
commit94545ee7be121f6bf31696d9f14edf4ebc62adf4 (patch)
tree60f1cfada19be2e76ee084400c487a69330ce32a
parent6d0a0e46b987dbc69a5694ff03d53d7e7e25b065 (diff)
downloadmongo-94545ee7be121f6bf31696d9f14edf4ebc62adf4.tar.gz
SERVER-43304 Modernize mr1.js
This reverts commit be1be55d991f7bed4d3896f5be53afbb4e579729.
-rw-r--r--buildscripts/resmokeconfig/suites/logical_session_cache_sharding_100ms_refresh_jscore_passthrough.yml2
-rw-r--r--buildscripts/resmokeconfig/suites/logical_session_cache_sharding_10sec_refresh_jscore_passthrough.yml2
-rw-r--r--buildscripts/resmokeconfig/suites/logical_session_cache_sharding_1sec_refresh_jscore_passthrough.yml2
-rw-r--r--buildscripts/resmokeconfig/suites/logical_session_cache_sharding_default_refresh_jscore_passthrough.yml2
-rw-r--r--buildscripts/resmokeconfig/suites/multi_shard_local_read_write_multi_stmt_txn_jscore_passthrough.yml2
-rw-r--r--buildscripts/resmokeconfig/suites/multi_shard_multi_stmt_txn_jscore_passthrough.yml2
-rw-r--r--buildscripts/resmokeconfig/suites/multi_shard_multi_stmt_txn_kill_primary_jscore_passthrough.yml2
-rw-r--r--buildscripts/resmokeconfig/suites/multi_shard_multi_stmt_txn_stepdown_primary_jscore_passthrough.yml2
-rw-r--r--buildscripts/resmokeconfig/suites/multi_stmt_txn_jscore_passthrough_with_migration.yml2
-rw-r--r--buildscripts/resmokeconfig/suites/sharded_causally_consistent_jscore_passthrough.yml2
-rw-r--r--jstests/core/mr1.js203
-rw-r--r--jstests/core/mr_correctness.js196
12 files changed, 206 insertions, 213 deletions
diff --git a/buildscripts/resmokeconfig/suites/logical_session_cache_sharding_100ms_refresh_jscore_passthrough.yml b/buildscripts/resmokeconfig/suites/logical_session_cache_sharding_100ms_refresh_jscore_passthrough.yml
index 66bb144b1e8..40c941c36b0 100644
--- a/buildscripts/resmokeconfig/suites/logical_session_cache_sharding_100ms_refresh_jscore_passthrough.yml
+++ b/buildscripts/resmokeconfig/suites/logical_session_cache_sharding_100ms_refresh_jscore_passthrough.yml
@@ -91,7 +91,7 @@ selector:
- jstests/core/sort_array.js
# TODO: SERVER-16605
- jstests/core/mr_index.js
- - jstests/core/mr1.js
+ - jstests/core/mr_correctness.js
- jstests/core/mr3.js
- jstests/core/mr4.js
- jstests/core/mr5.js
diff --git a/buildscripts/resmokeconfig/suites/logical_session_cache_sharding_10sec_refresh_jscore_passthrough.yml b/buildscripts/resmokeconfig/suites/logical_session_cache_sharding_10sec_refresh_jscore_passthrough.yml
index 4c8be72d6d8..6a5c3202daf 100644
--- a/buildscripts/resmokeconfig/suites/logical_session_cache_sharding_10sec_refresh_jscore_passthrough.yml
+++ b/buildscripts/resmokeconfig/suites/logical_session_cache_sharding_10sec_refresh_jscore_passthrough.yml
@@ -91,7 +91,7 @@ selector:
- jstests/core/sort_array.js
# TODO: SERVER-16605
- jstests/core/mr_index.js
- - jstests/core/mr1.js
+ - jstests/core/mr_correctness.js
- jstests/core/mr3.js
- jstests/core/mr4.js
- jstests/core/mr5.js
diff --git a/buildscripts/resmokeconfig/suites/logical_session_cache_sharding_1sec_refresh_jscore_passthrough.yml b/buildscripts/resmokeconfig/suites/logical_session_cache_sharding_1sec_refresh_jscore_passthrough.yml
index b102942e52c..a75bc546375 100644
--- a/buildscripts/resmokeconfig/suites/logical_session_cache_sharding_1sec_refresh_jscore_passthrough.yml
+++ b/buildscripts/resmokeconfig/suites/logical_session_cache_sharding_1sec_refresh_jscore_passthrough.yml
@@ -91,7 +91,7 @@ selector:
- jstests/core/sort_array.js
# TODO: SERVER-16605
- jstests/core/mr_index.js
- - jstests/core/mr1.js
+ - jstests/core/mr_correctness.js
- jstests/core/mr3.js
- jstests/core/mr4.js
- jstests/core/mr5.js
diff --git a/buildscripts/resmokeconfig/suites/logical_session_cache_sharding_default_refresh_jscore_passthrough.yml b/buildscripts/resmokeconfig/suites/logical_session_cache_sharding_default_refresh_jscore_passthrough.yml
index 89ea274bd8b..4ec3bf5be73 100644
--- a/buildscripts/resmokeconfig/suites/logical_session_cache_sharding_default_refresh_jscore_passthrough.yml
+++ b/buildscripts/resmokeconfig/suites/logical_session_cache_sharding_default_refresh_jscore_passthrough.yml
@@ -91,7 +91,7 @@ selector:
- jstests/core/sort_array.js
# TODO: SERVER-16605
- jstests/core/mr_index.js
- - jstests/core/mr1.js
+ - jstests/core/mr_correctness.js
- jstests/core/mr3.js
- jstests/core/mr4.js
- jstests/core/mr5.js
diff --git a/buildscripts/resmokeconfig/suites/multi_shard_local_read_write_multi_stmt_txn_jscore_passthrough.yml b/buildscripts/resmokeconfig/suites/multi_shard_local_read_write_multi_stmt_txn_jscore_passthrough.yml
index 1072d1c9570..50ec6ff4690 100644
--- a/buildscripts/resmokeconfig/suites/multi_shard_local_read_write_multi_stmt_txn_jscore_passthrough.yml
+++ b/buildscripts/resmokeconfig/suites/multi_shard_local_read_write_multi_stmt_txn_jscore_passthrough.yml
@@ -85,7 +85,7 @@ selector:
- jstests/core/optimized_match_explain.js
- jstests/core/sort_array.js
# TODO: SERVER-16605 MapReduce into sharded collection with hashed index fails
- - jstests/core/mr1.js
+ - jstests/core/mr_correctness.js
- jstests/core/mr3.js
- jstests/core/mr4.js
diff --git a/buildscripts/resmokeconfig/suites/multi_shard_multi_stmt_txn_jscore_passthrough.yml b/buildscripts/resmokeconfig/suites/multi_shard_multi_stmt_txn_jscore_passthrough.yml
index 2593d8ffc0b..207f84cd928 100644
--- a/buildscripts/resmokeconfig/suites/multi_shard_multi_stmt_txn_jscore_passthrough.yml
+++ b/buildscripts/resmokeconfig/suites/multi_shard_multi_stmt_txn_jscore_passthrough.yml
@@ -85,7 +85,7 @@ selector:
- jstests/core/optimized_match_explain.js
- jstests/core/sort_array.js
# TODO: SERVER-16605 MapReduce into sharded collection with hashed index fails
- - jstests/core/mr1.js
+ - jstests/core/mr_correctness.js
- jstests/core/mr3.js
- jstests/core/mr4.js
diff --git a/buildscripts/resmokeconfig/suites/multi_shard_multi_stmt_txn_kill_primary_jscore_passthrough.yml b/buildscripts/resmokeconfig/suites/multi_shard_multi_stmt_txn_kill_primary_jscore_passthrough.yml
index 5a154c63cc4..b1983e9082f 100644
--- a/buildscripts/resmokeconfig/suites/multi_shard_multi_stmt_txn_kill_primary_jscore_passthrough.yml
+++ b/buildscripts/resmokeconfig/suites/multi_shard_multi_stmt_txn_kill_primary_jscore_passthrough.yml
@@ -85,7 +85,7 @@ selector:
- jstests/core/optimized_match_explain.js
- jstests/core/sort_array.js
# TODO: SERVER-16605 MapReduce into sharded collection with hashed index fails
- - jstests/core/mr1.js
+ - jstests/core/mr_correctness.js
- jstests/core/mr3.js
- jstests/core/mr4.js
diff --git a/buildscripts/resmokeconfig/suites/multi_shard_multi_stmt_txn_stepdown_primary_jscore_passthrough.yml b/buildscripts/resmokeconfig/suites/multi_shard_multi_stmt_txn_stepdown_primary_jscore_passthrough.yml
index 2cca2cfbcdd..8850efcc8d0 100644
--- a/buildscripts/resmokeconfig/suites/multi_shard_multi_stmt_txn_stepdown_primary_jscore_passthrough.yml
+++ b/buildscripts/resmokeconfig/suites/multi_shard_multi_stmt_txn_stepdown_primary_jscore_passthrough.yml
@@ -85,7 +85,7 @@ selector:
- jstests/core/optimized_match_explain.js
- jstests/core/sort_array.js
# TODO: SERVER-16605 MapReduce into sharded collection with hashed index fails
- - jstests/core/mr1.js
+ - jstests/core/mr_correctness.js
- jstests/core/mr3.js
- jstests/core/mr4.js
diff --git a/buildscripts/resmokeconfig/suites/multi_stmt_txn_jscore_passthrough_with_migration.yml b/buildscripts/resmokeconfig/suites/multi_stmt_txn_jscore_passthrough_with_migration.yml
index f3a6c31672b..fd2921b5ef7 100644
--- a/buildscripts/resmokeconfig/suites/multi_stmt_txn_jscore_passthrough_with_migration.yml
+++ b/buildscripts/resmokeconfig/suites/multi_stmt_txn_jscore_passthrough_with_migration.yml
@@ -85,7 +85,7 @@ selector:
- jstests/core/optimized_match_explain.js
- jstests/core/sort_array.js
# TODO: SERVER-16605 MapReduce into sharded collection with hashed index fails
- - jstests/core/mr1.js
+ - jstests/core/mr_correctness.js
- jstests/core/mr3.js
- jstests/core/mr4.js
# Create index command arbitrarily picks one of the errors if there are multiple errors from the
diff --git a/buildscripts/resmokeconfig/suites/sharded_causally_consistent_jscore_passthrough.yml b/buildscripts/resmokeconfig/suites/sharded_causally_consistent_jscore_passthrough.yml
index 8cee5e28e21..30a3f185a2a 100644
--- a/buildscripts/resmokeconfig/suites/sharded_causally_consistent_jscore_passthrough.yml
+++ b/buildscripts/resmokeconfig/suites/sharded_causally_consistent_jscore_passthrough.yml
@@ -63,7 +63,7 @@ selector:
# collection is sharded on anything other than {_id: 1}.
- jstests/core/mr_undef.js
# TODO: SERVER-16605
- - jstests/core/mr1.js
+ - jstests/core/mr_correctness.js
- jstests/core/mr3.js
- jstests/core/mr4.js
# TODO: SERVER-30052
diff --git a/jstests/core/mr1.js b/jstests/core/mr1.js
deleted file mode 100644
index d43b6b8303a..00000000000
--- a/jstests/core/mr1.js
+++ /dev/null
@@ -1,203 +0,0 @@
-// @tags: [
-// # mapReduce does not support afterClusterTime.
-// does_not_support_causal_consistency,
-// does_not_support_stepdowns,
-// requires_fastcount,
-// requires_getmore,
-// uses_map_reduce_with_temp_collections,
-// ]
-
-t = db.mr1;
-t.drop();
-
-t.save({x: 1, tags: ["a", "b"]});
-t.save({x: 2, tags: ["b", "c"]});
-t.save({x: 3, tags: ["c", "a"]});
-t.save({x: 4, tags: ["b", "c"]});
-
-emit = printjson;
-
-function d(x) {
- printjson(x);
-}
-
-ks = "_id";
-if (db.version() == "1.1.1")
- ks = "key";
-
-m = function() {
- this.tags.forEach(function(z) {
- emit(z, {count: 1});
- });
-};
-
-m2 = function() {
- for (var i = 0; i < this.tags.length; i++) {
- emit(this.tags[i], 1);
- }
-};
-
-r = function(key, values) {
- var total = 0;
- for (var i = 0; i < values.length; i++) {
- total += values[i].count;
- }
- return {count: total};
-};
-
-r2 = function(key, values) {
- var total = 0;
- for (var i = 0; i < values.length; i++) {
- total += values[i];
- }
- return total;
-};
-
-res = db.runCommand({mapreduce: "mr1", map: m, reduce: r, out: "mr1_out"});
-d(res);
-if (ks == "_id")
- assert(res.ok, "not ok");
-assert.eq(4, res.counts.input, "A");
-x = db[res.result];
-
-assert.eq(3, x.find().count(), "B");
-x.find().forEach(d);
-z = {};
-x.find().forEach(function(a) {
- z[a[ks]] = a.value.count;
-});
-d(z);
-assert.eq(3, Object.keySet(z).length, "C");
-assert.eq(2, z.a, "D");
-assert.eq(3, z.b, "E");
-assert.eq(3, z.c, "F");
-x.drop();
-
-res = db.runCommand({mapreduce: "mr1", map: m, reduce: r, query: {x: {"$gt": 2}}, out: "mr1_out"});
-d(res);
-assert.eq(2, res.counts.input, "B");
-x = db[res.result];
-z = {};
-x.find().forEach(function(a) {
- z[a[ks]] = a.value.count;
-});
-assert.eq(1, z.a, "C1");
-assert.eq(1, z.b, "C2");
-assert.eq(2, z.c, "C3");
-x.drop();
-
-res =
- db.runCommand({mapreduce: "mr1", map: m2, reduce: r2, query: {x: {"$gt": 2}}, out: "mr1_out"});
-d(res);
-assert.eq(2, res.counts.input, "B");
-x = db[res.result];
-z = {};
-x.find().forEach(function(a) {
- z[a[ks]] = a.value;
-});
-assert.eq(1, z.a, "C1z");
-assert.eq(1, z.b, "C2z");
-assert.eq(2, z.c, "C3z");
-x.drop();
-
-res = db.runCommand({mapreduce: "mr1", out: "mr1_foo", map: m, reduce: r, query: {x: {"$gt": 2}}});
-d(res);
-assert.eq(2, res.counts.input, "B2");
-assert.eq("mr1_foo", res.result, "B2-c");
-x = db[res.result];
-z = {};
-x.find().forEach(function(a) {
- z[a[ks]] = a.value.count;
-});
-assert.eq(1, z.a, "C1a");
-assert.eq(1, z.b, "C2a");
-assert.eq(2, z.c, "C3a");
-x.drop();
-
-for (i = 5; i < 1000; i++) {
- t.save({x: i, tags: ["b", "d"]});
-}
-
-res = db.runCommand({mapreduce: "mr1", map: m, reduce: r, out: "mr1_out"});
-d(res);
-assert.eq(999, res.counts.input, "Z1");
-x = db[res.result];
-x.find().forEach(d);
-assert.eq(4, x.find().count(), "Z2");
-assert.eq("a,b,c,d", x.distinct(ks), "Z3");
-
-function getk(k) {
- var o = {};
- o[ks] = k;
- return x.findOne(o);
-}
-
-assert.eq(2, getk("a").value.count, "ZA");
-assert.eq(998, getk("b").value.count, "ZB");
-assert.eq(3, getk("c").value.count, "ZC");
-assert.eq(995, getk("d").value.count, "ZD");
-x.drop();
-
-if (true) {
- printjson(db.runCommand({mapreduce: "mr1", map: m, reduce: r, verbose: true, out: "mr1_out"}));
-}
-
-print("t1: " + Date.timeFunc(function() {
- var out = db.runCommand({mapreduce: "mr1", map: m, reduce: r, out: "mr1_out"});
- if (ks == "_id")
- assert(out.ok, "XXX : " + tojson(out));
- db[out.result].drop();
-}, 10) + " (~500 on 2.8ghz) - itcount: " + Date.timeFunc(function() {
- db.mr1.find().itcount();
-}, 10));
-
-// test doesn't exist
-res =
- db.runCommand({mapreduce: "lasjdlasjdlasjdjasldjalsdj12e", map: m, reduce: r, out: "mr1_out"});
-assert(!res.ok, "should be not ok");
-
-if (true) {
- correct = {};
-
- var bulk = t.initializeUnorderedBulkOp();
- for (i = 0; i < 20000; i++) {
- k = "Z" + i % 10000;
- if (correct[k])
- correct[k]++;
- else
- correct[k] = 1;
- bulk.insert({x: i, tags: [k]});
- }
- assert.commandWorked(bulk.execute());
-
- res = db.runCommand({mapreduce: "mr1", out: "mr1_foo", map: m, reduce: r});
- d(res);
- print("t2: " + res.timeMillis + " (~3500 on 2.8ghz) - itcount: " + Date.timeFunc(function() {
- db.mr1.find().itcount();
- }));
- x = db[res.result];
- z = {};
- x.find().forEach(function(a) {
- z[a[ks]] = a.value.count;
- });
- for (zz in z) {
- if (zz.indexOf("Z") == 0) {
- assert.eq(correct[zz], z[zz], "ZZ : " + zz);
- }
- }
- x.drop();
-
- res = db.runCommand({mapreduce: "mr1", out: "mr1_out", map: m2, reduce: r2});
- d(res);
- print("t3: " + res.timeMillis + " (~3500 on 2.8ghz)");
-
- res = db.runCommand({mapreduce: "mr1", map: m2, reduce: r2, out: {inline: true}});
- print("t4: " + res.timeMillis);
-}
-
-res = db.runCommand({mapreduce: "mr1", map: m, reduce: r, out: "mr1_out"});
-assert(res.ok, "should be ok");
-
-t.drop();
-t1 = db.mr1_out;
-t1.drop();
diff --git a/jstests/core/mr_correctness.js b/jstests/core/mr_correctness.js
new file mode 100644
index 00000000000..466e5bc1b32
--- /dev/null
+++ b/jstests/core/mr_correctness.js
@@ -0,0 +1,196 @@
+// Basic correctness tests for the mapReduce command.
+// @tags: [
+// # mapReduce does not support afterClusterTime.
+// does_not_support_causal_consistency,
+// does_not_support_stepdowns,
+// requires_fastcount,
+// requires_getmore,
+// uses_map_reduce_with_temp_collections,
+// ]
+(function() {
+"use strict";
+load("jstests/libs/fixture_helpers.js"); // For "FixtureHelpers".
+
+const coll = db.mr_correctness;
+coll.drop();
+
+assert.commandWorked(coll.insert({x: 1, tags: ["a", "b"]}));
+assert.commandWorked(coll.insert({x: 2, tags: ["b", "c"]}));
+assert.commandWorked(coll.insert({x: 3, tags: ["c", "a"]}));
+assert.commandWorked(coll.insert({x: 4, tags: ["b", "c"]}));
+
+function mapToObj() {
+ this.tags.forEach(function(z) {
+ emit(z, {count: 1});
+ });
+}
+
+function reduceObjs(key, values) {
+ let total = 0;
+ for (let i = 0; i < values.length; i++) {
+ total += values[i].count;
+ }
+ return {count: total};
+}
+
+const outColl = db[coll.getName() + "_out"];
+outColl.drop();
+(function testBasicMapReduce() {
+ const res = db.runCommand(
+ {mapReduce: coll.getName(), map: mapToObj, reduce: reduceObjs, out: outColl.getName()});
+ assert.commandWorked(res);
+ assert.eq(4, res.counts.input);
+ assert.eq(res.result, outColl.getName());
+
+ assert.eq(
+ 3,
+ outColl.find().count(),
+ () =>
+ `expected 3 distinct tags: ['a', 'b', 'c'], found ${tojson(outColl.find().toArray())}`);
+ const keys = {};
+ for (let result of outColl.find().toArray()) {
+ keys[result._id] = result.value.count;
+ }
+ assert.eq(3, Object.keySet(keys).length, Object.keySet(keys));
+ assert.eq(2, keys.a, () => `Expected 2 occurences of the tag 'a': ${tojson(keys)}`);
+ assert.eq(3, keys.b, () => `Expected 3 occurences of the tag 'b': ${tojson(keys)}`);
+ assert.eq(3, keys.c, () => `Expected 3 occurences of the tag 'c': ${tojson(keys)}`);
+ outColl.drop();
+})();
+
+(function testMapReduceWithPredicate() {
+ const res = db.runCommand({
+ mapReduce: coll.getName(),
+ map: mapToObj,
+ reduce: reduceObjs,
+ query: {x: {$gt: 2}},
+ out: outColl.getName()
+ });
+ assert.commandWorked(res);
+ assert.eq(2, res.counts.input, () => tojson(res));
+ assert.eq(res.result, outColl.getName());
+ const keys = {};
+ for (let result of outColl.find().toArray()) {
+ keys[result._id] = result.value.count;
+ }
+ assert.eq(3, Object.keySet(keys).length, Object.keySet(keys));
+ assert.eq(1, keys.a, () => `Expected 1 occurence of the tag 'a': ${tojson(keys)}`);
+ assert.eq(1, keys.b, () => `Expected 1 occurence of the tag 'b': ${tojson(keys)}`);
+ assert.eq(2, keys.c, () => `Expected 2 occurences of the tag 'c': ${tojson(keys)}`);
+ outColl.drop();
+}());
+
+function mapToNumber() {
+ for (let tag of this.tags) {
+ emit(tag, 1);
+ }
+}
+
+function reduceNumbers(key, values) {
+ let total = 0;
+ for (let val of values) {
+ total += val;
+ }
+ return total;
+}
+
+// Now do a similar test but using the above map and reduce functions which use numbers as the value
+// instead of objects.
+(function testBasicMapReduceWithNumberValues() {
+ const res = db.runCommand({
+ mapReduce: coll.getName(),
+ map: mapToNumber,
+ reduce: reduceNumbers,
+ query: {x: {$gt: 2}},
+ out: outColl.getName()
+ });
+ assert.commandWorked(res);
+ assert.eq(2, res.counts.input, () => tojson(res));
+ assert.eq(res.result, outColl.getName());
+ const keys = {};
+ for (let result of outColl.find().toArray()) {
+ keys[result._id] = result.value;
+ }
+ assert.eq(3, Object.keySet(keys).length, Object.keySet(keys));
+ assert.eq(1, keys.a, () => `Expected 1 occurence of the tag 'a': ${tojson(keys)}`);
+ assert.eq(1, keys.b, () => `Expected 1 occurence of the tag 'b': ${tojson(keys)}`);
+ assert.eq(2, keys.c, () => `Expected 2 occurences of the tag 'c': ${tojson(keys)}`);
+ outColl.drop();
+}());
+
+(function testMapReduceWithManyValuesGrouped() {
+ const bulk = coll.initializeUnorderedBulkOp();
+ for (let i = 5; i < 1000; i++) {
+ bulk.insert({x: i, tags: ["b", "d"]});
+ }
+ assert.commandWorked(bulk.execute());
+
+ const res = db.runCommand(
+ {mapReduce: coll.getName(), map: mapToObj, reduce: reduceObjs, out: outColl.getName()});
+ assert.commandWorked(res);
+ assert.eq(999, res.counts.input, () => tojson(res));
+ assert.eq(res.result, outColl.getName());
+ assert.eq(4,
+ outColl.find().count(),
+ () => `expected 4 distinct tags: ['a', 'b', 'c', 'd'], found ${
+ tojson(outColl.find().toArray())}`);
+ assert.eq("a,b,c,d", outColl.distinct("_id"));
+
+ assert.eq(2, outColl.findOne({_id: "a"}).value.count, () => outColl.findOne({_id: "a"}));
+ assert.eq(998, outColl.findOne({_id: "b"}).value.count, () => outColl.findOne({_id: "b"}));
+ assert.eq(3, outColl.findOne({_id: "c"}).value.count, () => outColl.findOne({_id: "c"}));
+ assert.eq(995, outColl.findOne({_id: "d"}).value.count, () => outColl.findOne({_id: "d"}));
+ outColl.drop();
+}());
+
+(function testThatVerboseOptionIncludesTimingInformation() {
+ const cmd =
+ {mapReduce: coll.getName(), map: mapToObj, reduce: reduceObjs, out: outColl.getName()};
+ const withoutVerbose = assert.commandWorked(db.runCommand(cmd));
+ // TODO SERVER-43290 The verbose option should have the same effect on mongos.
+ assert(FixtureHelpers.isMongos(db) || !withoutVerbose.hasOwnProperty("timing"));
+ const withVerbose = assert.commandWorked(db.runCommand(Object.merge(cmd, {verbose: true})));
+ assert(withVerbose.hasOwnProperty("timing"));
+}());
+
+(function testMapReduceAgainstNonExistentCollection() {
+ assert.commandFailedWithCode(db.runCommand({
+ mapReduce: "lasjdlasjdlasjdjasldjalsdj12e",
+ map: mapToObj,
+ reduce: reduceObjs,
+ out: outColl.getName()
+ }),
+ ErrorCodes.NamespaceNotFound);
+}());
+
+(function testHighCardinalityKeySet() {
+ let correctValues = {};
+
+ coll.drop();
+ const bulk = coll.initializeUnorderedBulkOp();
+ for (let i = 0; i < 20000; i++) {
+ const tag = "Z" + i % 10000;
+ if (!correctValues[tag])
+ correctValues[tag] = 1;
+ else
+ correctValues[tag]++;
+ bulk.insert({x: i, tags: [tag]});
+ }
+ assert.commandWorked(bulk.execute());
+
+ const res = db.runCommand(
+ {mapReduce: coll.getName(), out: outColl.getName(), map: mapToObj, reduce: reduceObjs});
+ assert.commandWorked(res);
+ assert.eq(res.result, outColl.getName());
+ let actualValues = {};
+ outColl.find().forEach(function(resultDoc) {
+ actualValues[resultDoc._id] = resultDoc.value.count;
+ });
+ for (let key in actualValues) {
+ assert.eq(correctValues[key], actualValues[key], key);
+ }
+}());
+
+coll.drop();
+outColl.drop();
+}());