diff options
author | David Storch <david.storch@10gen.com> | 2016-06-21 16:41:28 -0400 |
---|---|---|
committer | David Storch <david.storch@10gen.com> | 2016-06-22 21:04:41 -0400 |
commit | ab502aa503b9f84e0787854d18da274b42624f4e (patch) | |
tree | 9699f0b81f927ae4e616a479909a8b7c0e76f984 | |
parent | e18129b702ff4cb132ac8fe4c6dc225466b0e311 (diff) | |
download | mongo-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.yml | 2 | ||||
-rw-r--r-- | jstests/sharding/mapReduce_inSharded.js | 145 | ||||
-rw-r--r-- | src/mongo/s/commands/cluster_map_reduce_cmd.cpp | 5 |
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 |