0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-12-01 09:32:32 +01:00
mongodb/jstests/sharding/explain_find_and_modify_sharded.js

109 lines
3.7 KiB
JavaScript

/*
* Test that the explain command supports findAndModify when talking to a mongos
* and the collection is sharded.
*/
(function() {
'use strict';
var collName = 'explain_find_and_modify';
// Create a cluster with 2 shards.
var st = new ShardingTest({shards: 2});
st.stopBalancer();
var testDB = st.s.getDB('test');
var shardKey = {a: 1};
// Create a collection with an index on the intended shard key.
var shardedColl = testDB.getCollection(collName);
shardedColl.drop();
assert.commandWorked(testDB.createCollection(collName));
assert.commandWorked(shardedColl.ensureIndex(shardKey));
// Enable sharding on the database and shard the collection.
// Use "shard0000" as the primary shard.
assert.commandWorked(testDB.adminCommand({enableSharding: testDB.getName()}));
var res = testDB.adminCommand({movePrimary: testDB.getName(), to: 'shard0000'});
assert(res.ok || res.errmsg == "it is already the primary");
assert.commandWorked(testDB.adminCommand({
shardCollection: shardedColl.getFullName(),
key: shardKey
}));
// Split and move the chunks so that
// chunk { "a" : { "$minKey" : 1 } } -->> { "a" : 10 } is on shard0000
// chunk { "a" : 10 } -->> { "a" : { "$maxKey" : 1 } } is on shard0001
assert.commandWorked(testDB.adminCommand({
split: shardedColl.getFullName(),
middle: {a: 10}
}));
assert.commandWorked(testDB.adminCommand({
moveChunk: shardedColl.getFullName(),
find: {a: 10},
to: 'shard0001'
}));
var res;
// Queries that do not involve the shard key are invalid.
res = testDB.runCommand({
explain: {
findAndModify: collName,
query: {b: 1},
remove: true
},
verbosity: 'queryPlanner'
});
assert.commandFailed(res);
// Queries that have non-equality queries on the shard key are invalid.
res = testDB.runCommand({
explain: {
findAndModify: collName,
query: {a: {$gt: 5}},
update: {$inc: {b: 7}},
},
verbosity: 'allPlansExecution'
});
assert.commandFailed(res);
// Asserts that the explain command ran on the specified shard and used the given stage
// for performing the findAndModify command.
function assertExplainResult(explainOut, outerKey, innerKey, shardName, expectedStage) {
assert(explainOut.hasOwnProperty(outerKey));
assert(explainOut[outerKey].hasOwnProperty(innerKey));
var shardStage = explainOut[outerKey][innerKey];
assert.eq('SINGLE_SHARD', shardStage.stage);
assert.eq(1, shardStage.shards.length);
assert.eq(shardName, shardStage.shards[0].shardName);
assert.eq(expectedStage, shardStage.shards[0][innerKey].stage);
}
// Test that the explain command is routed to "shard0000" when targeting the lower chunk range.
res = testDB.runCommand({
explain: {
findAndModify: collName,
query: {a: 0},
update: {$inc: {b: 7}},
upsert: true
},
verbosity: 'queryPlanner'
});
assert.commandWorked(res);
assertExplainResult(res, 'queryPlanner', 'winningPlan', 'shard0000', 'UPDATE');
// Test that the explain command is routed to "shard0001" when targeting the higher chunk range.
res = testDB.runCommand({
explain: {
findAndModify: collName,
query: {a: 20, c: 5},
remove: true
},
verbosity: 'executionStats'
});
assert.commandWorked(res);
assertExplainResult(res, 'executionStats', 'executionStages', 'shard0001', 'DELETE');
})();