summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Storch <david.storch@10gen.com>2016-06-21 16:41:28 -0400
committerDavid Storch <david.storch@10gen.com>2016-06-22 21:04:41 -0400
commitab502aa503b9f84e0787854d18da274b42624f4e (patch)
tree9699f0b81f927ae4e616a479909a8b7c0e76f984
parente18129b702ff4cb132ac8fe4c6dc225466b0e311 (diff)
downloadmongo-ab502aa503b9f84e0787854d18da274b42624f4e.tar.gz
SERVER-24405 make sharded mapReduce forward collation when input collection is sharded
-rw-r--r--buildscripts/resmokeconfig/suites/sharding_last_stable_mongos.yml2
-rw-r--r--jstests/sharding/mapReduce_inSharded.js145
-rw-r--r--src/mongo/s/commands/cluster_map_reduce_cmd.cpp5
3 files changed, 89 insertions, 63 deletions
diff --git a/buildscripts/resmokeconfig/suites/sharding_last_stable_mongos.yml b/buildscripts/resmokeconfig/suites/sharding_last_stable_mongos.yml
index 1d75bab8814..7db761001ff 100644
--- a/buildscripts/resmokeconfig/suites/sharding_last_stable_mongos.yml
+++ b/buildscripts/resmokeconfig/suites/sharding_last_stable_mongos.yml
@@ -26,6 +26,8 @@ selector:
- jstests/sharding/printShardingStatus.js
# TODO: Change in error reporting, enable when 3.4 becomes 'last-stable'.
- jstests/sharding/map_reduce_validation.js
+ # TODO Assumes mapReduce can handle the collation option; enable when 3.4 becomes 'last-stable'.
+ - jstests/sharding/mapReduce_inSharded.js
executor:
js_test:
diff --git a/jstests/sharding/mapReduce_inSharded.js b/jstests/sharding/mapReduce_inSharded.js
index 110be371ba9..52eb379e1fd 100644
--- a/jstests/sharding/mapReduce_inSharded.js
+++ b/jstests/sharding/mapReduce_inSharded.js
@@ -1,62 +1,85 @@
-var verifyOutput = function(out) {
- printjson(out);
- assert.eq(out.counts.input, 51200, "input count is wrong");
- assert.eq(out.counts.emit, 51200, "emit count is wrong");
- assert.gt(out.counts.reduce, 99, "reduce count is wrong");
- assert.eq(out.counts.output, 512, "output count is wrong");
-};
-
-var st = new ShardingTest(
- {shards: 2, verbose: 1, mongos: 1, other: {chunkSize: 1, enableBalancer: true}});
-
-st.adminCommand({enablesharding: "mrShard"});
-st.ensurePrimaryShard('mrShard', 'shard0001');
-st.adminCommand({shardcollection: "mrShard.srcSharded", key: {"_id": 1}});
-
-var db = st.getDB("mrShard");
-
-var bulk = db.srcSharded.initializeUnorderedBulkOp();
-for (j = 0; j < 100; j++) {
- for (i = 0; i < 512; i++) {
- bulk.insert({j: j, i: i});
+(function() {
+ "use strict";
+
+ var verifyOutput = function(out) {
+ printjson(out);
+ assert.commandWorked(out);
+ assert.eq(out.counts.input, 51200, "input count is wrong");
+ assert.eq(out.counts.emit, 51200, "emit count is wrong");
+ assert.gt(out.counts.reduce, 99, "reduce count is wrong");
+ assert.eq(out.counts.output, 512, "output count is wrong");
+ };
+
+ var st = new ShardingTest(
+ {shards: 2, verbose: 1, mongos: 1, other: {chunkSize: 1, enableBalancer: true}});
+
+ st.adminCommand({enablesharding: "mrShard"});
+ st.ensurePrimaryShard('mrShard', 'shard0001');
+ st.adminCommand({shardcollection: "mrShard.srcSharded", key: {"_id": 1}});
+
+ var db = st.getDB("mrShard");
+
+ var bulk = db.srcSharded.initializeUnorderedBulkOp();
+ for (var j = 0; j < 100; j++) {
+ for (var i = 0; i < 512; i++) {
+ bulk.insert({j: j, i: i});
+ }
}
-}
-assert.writeOK(bulk.execute());
-
-function map() {
- emit(this.i, 1);
-}
-function reduce(key, values) {
- return Array.sum(values);
-}
-
-// sharded src
-var suffix = "InSharded";
-
-var out = db.srcSharded.mapReduce(map, reduce, "mrBasic" + suffix);
-verifyOutput(out);
-
-out = db.srcSharded.mapReduce(map, reduce, {out: {replace: "mrReplace" + suffix}});
-verifyOutput(out);
-
-out = db.srcSharded.mapReduce(map, reduce, {out: {merge: "mrMerge" + suffix}});
-verifyOutput(out);
-
-out = db.srcSharded.mapReduce(map, reduce, {out: {reduce: "mrReduce" + suffix}});
-verifyOutput(out);
-
-out = db.srcSharded.mapReduce(map, reduce, {out: {inline: 1}});
-verifyOutput(out);
-assert(out.results != 'undefined', "no results for inline");
-
-out = db.srcSharded.mapReduce(
- map, reduce, {out: {replace: "mrReplace" + suffix, db: "mrShardOtherDB"}});
-verifyOutput(out);
-
-out = db.runCommand({
- mapReduce: "srcSharded", // use new name mapReduce rather than mapreduce
- map: map,
- reduce: reduce,
- out: "mrBasic" + "srcSharded",
-});
-verifyOutput(out);
+ assert.writeOK(bulk.execute());
+
+ function map() {
+ emit(this.i, 1);
+ }
+ function reduce(key, values) {
+ return Array.sum(values);
+ }
+
+ // sharded src
+ var suffix = "InSharded";
+
+ var out = db.srcSharded.mapReduce(map, reduce, "mrBasic" + suffix);
+ verifyOutput(out);
+
+ out = db.srcSharded.mapReduce(map, reduce, {out: {replace: "mrReplace" + suffix}});
+ verifyOutput(out);
+
+ out = db.srcSharded.mapReduce(map, reduce, {out: {merge: "mrMerge" + suffix}});
+ verifyOutput(out);
+
+ out = db.srcSharded.mapReduce(map, reduce, {out: {reduce: "mrReduce" + suffix}});
+ verifyOutput(out);
+
+ out = db.srcSharded.mapReduce(map, reduce, {out: {inline: 1}});
+ verifyOutput(out);
+ assert(out.results != 'undefined', "no results for inline");
+
+ // Ensure that mapReduce with a sharded input collection can accept the collation option.
+ out = db.srcSharded.mapReduce(map, reduce, {out: {inline: 1}, collation: {locale: "en_US"}});
+ verifyOutput(out);
+ assert(out.results != 'undefined', "no results for inline with collation");
+
+ out = db.srcSharded.mapReduce(
+ map, reduce, {out: {replace: "mrReplace" + suffix, db: "mrShardOtherDB"}});
+ verifyOutput(out);
+
+ out = db.runCommand({
+ mapReduce: "srcSharded", // use new name mapReduce rather than mapreduce
+ map: map,
+ reduce: reduce,
+ out: "mrBasic" + "srcSharded",
+ });
+ verifyOutput(out);
+
+ // Ensure that the collation option is propagated to the shards. This uses a case-insensitive
+ // collation, and the query seeding the mapReduce should only match the document if the
+ // collation is passed along to the shards.
+ assert.writeOK(db.srcSharded.remove({}));
+ assert.eq(db.srcSharded.find().itcount(), 0);
+ assert.writeOK(db.srcSharded.insert({i: 0, j: 0, str: "FOO"}));
+ out = db.srcSharded.mapReduce(
+ map,
+ reduce,
+ {out: {inline: 1}, query: {str: "foo"}, collation: {locale: "en_US", strength: 2}});
+ assert.commandWorked(out);
+ assert.eq(out.counts.input, 1);
+})();
diff --git a/src/mongo/s/commands/cluster_map_reduce_cmd.cpp b/src/mongo/s/commands/cluster_map_reduce_cmd.cpp
index b8e7bb9e0c9..b5cf2df1861 100644
--- a/src/mongo/s/commands/cluster_map_reduce_cmd.cpp
+++ b/src/mongo/s/commands/cluster_map_reduce_cmd.cpp
@@ -93,8 +93,9 @@ BSONObj fixForShards(const BSONObj& orig,
if (fn == bypassDocumentValidationCommandOption() || fn == "map" || fn == "mapreduce" ||
fn == "mapReduce" || fn == "mapparams" || fn == "reduce" || fn == "query" ||
- fn == "sort" || fn == "scope" || fn == "verbose" || fn == "$queryOptions" ||
- fn == "readConcern" || fn == QueryRequest::cmdOptionMaxTimeMS) {
+ fn == "sort" || fn == "collation" || fn == "scope" || fn == "verbose" ||
+ fn == "$queryOptions" || fn == "readConcern" ||
+ fn == QueryRequest::cmdOptionMaxTimeMS) {
b.append(e);
} else if (fn == "out" || fn == "finalize" || fn == "writeConcern") {
// We don't want to copy these