mirror of https://github.com/mongodb/mongo
152 lines
4.8 KiB
JavaScript
152 lines
4.8 KiB
JavaScript
// Cannot implicitly shard accessed collections because of following errmsg: A single
|
|
// update/delete on a sharded collection must contain an exact match on _id or contain the shard
|
|
// key.
|
|
// @tags: [assumes_unsharded_collection, requires_fastcount, requires_fcv_44]
|
|
|
|
t = db.find_and_modify;
|
|
t.drop();
|
|
|
|
// fill db
|
|
for (var i = 1; i <= 10; i++) {
|
|
t.insert({priority: i, inprogress: false, value: 0});
|
|
}
|
|
|
|
// returns old
|
|
out = t.findAndModify({sort: {priority: 1}, update: {$set: {inprogress: true}, $inc: {value: 1}}});
|
|
assert.eq(out.value, 0);
|
|
assert.eq(out.inprogress, false);
|
|
t.update({_id: out._id}, {$set: {inprogress: false}});
|
|
|
|
// returns new
|
|
out = t.findAndModify(
|
|
{sort: {priority: 1}, update: {$set: {inprogress: true}, $inc: {value: 1}}, 'new': true});
|
|
assert.eq(out.value, 2);
|
|
assert.eq(out.inprogress, true);
|
|
t.update({_id: out._id}, {$set: {inprogress: false}});
|
|
|
|
// update highest priority
|
|
out = t.findAndModify(
|
|
{query: {inprogress: false}, sort: {priority: -1}, update: {$set: {inprogress: true}}});
|
|
assert.eq(out.priority, 10);
|
|
// update next highest priority
|
|
out = t.findAndModify(
|
|
{query: {inprogress: false}, sort: {priority: -1}, update: {$set: {inprogress: true}}});
|
|
assert.eq(out.priority, 9);
|
|
|
|
// Use expressions in the 'fields' argument with 'new' false.
|
|
out = t.findAndModify({
|
|
query: {inprogress: false},
|
|
sort: {priority: -1},
|
|
'new': false,
|
|
update: {$set: {inprogress: true}, $inc: {value: 1}},
|
|
fields: {priority: 1, inprogress: 1, computedField: {$add: ["$value", 2]}}
|
|
});
|
|
assert.eq(out.priority, 8);
|
|
assert.eq(out.inprogress, false);
|
|
// The projection should have been applied to the pre image of the update.
|
|
assert.eq(out.computedField, 2);
|
|
|
|
// Use expressions in the 'fields' argument with 'new' true.
|
|
out = t.findAndModify({
|
|
query: {inprogress: false},
|
|
sort: {priority: -1},
|
|
update: {$set: {inprogress: true}, $inc: {value: 1}},
|
|
'new': true,
|
|
fields: {priority: 1, inprogress: 1, computedField: {$add: ["$value", 2]}}
|
|
});
|
|
assert.eq(out.priority, 7);
|
|
assert.eq(out.inprogress, true);
|
|
// The projection should have been applied to the update post image.
|
|
assert.eq(out.computedField, 3);
|
|
|
|
// remove lowest priority
|
|
out = t.findAndModify({sort: {priority: 1}, remove: true});
|
|
assert.eq(out.priority, 1);
|
|
|
|
// remove next lowest priority
|
|
out = t.findAndModify({sort: {priority: 1}, remove: 1});
|
|
assert.eq(out.priority, 2);
|
|
|
|
// return null (was {} before 1.5.4) if no matches (drivers may handle this differently)
|
|
out = t.findAndModify({query: {no_such_field: 1}, remove: 1});
|
|
assert.eq(out, null);
|
|
|
|
// make sure we fail with conflicting params to findAndModify SERVER-16601
|
|
t.insert({x: 1});
|
|
assert.throws(function() {
|
|
t.findAndModify({query: {x: 1}, update: {y: 2}, remove: true});
|
|
});
|
|
assert.throws(function() {
|
|
t.findAndModify({query: {x: 1}, update: {y: 2}, remove: true, sort: {x: 1}});
|
|
});
|
|
assert.throws(function() {
|
|
t.findAndModify({query: {x: 1}, update: {y: 2}, remove: true, upsert: true});
|
|
});
|
|
assert.throws(function() {
|
|
t.findAndModify({query: {x: 1}, update: {y: 2}, new: true, remove: true});
|
|
});
|
|
assert.throws(function() {
|
|
t.findAndModify({query: {x: 1}, upsert: true, remove: true});
|
|
});
|
|
|
|
//
|
|
// SERVER-17387: Find and modify should throw in the case of invalid projection.
|
|
//
|
|
|
|
function runFindAndModify(shouldMatch, upsert, newParam) {
|
|
t.drop();
|
|
if (shouldMatch) {
|
|
assert.commandWorked(t.insert({_id: "found"}));
|
|
}
|
|
const query = shouldMatch ? "found" : "miss";
|
|
const res = db.runCommand({
|
|
findAndModify: t.getName(),
|
|
query: {_id: query},
|
|
update: {$inc: {y: 1}},
|
|
fields: {foo: {$pop: ["bar"]}},
|
|
upsert: upsert,
|
|
new: newParam
|
|
});
|
|
assert.commandFailedWithCode(res, 31325);
|
|
}
|
|
|
|
// Insert case.
|
|
runFindAndModify(false /* shouldMatch */, true /* upsert */, true /* new */);
|
|
|
|
// Update with upsert + new.
|
|
runFindAndModify(true /* shouldMatch */, true /* upsert */, true /* new */);
|
|
|
|
// Update with just new: true.
|
|
runFindAndModify(true /* shouldMatch */, false /* upsert */, true /* new */);
|
|
|
|
// Update with just upsert: true.
|
|
runFindAndModify(true /* shouldMatch */, true /* upsert */, false /* new */);
|
|
|
|
// Update with neither upsert nor new flags.
|
|
runFindAndModify(true /* shouldMatch */, false /* upsert */, false /* new */);
|
|
|
|
//
|
|
// SERVER-17372
|
|
//
|
|
|
|
t.drop();
|
|
cmdRes = db.runCommand(
|
|
{findAndModify: t.getName(), query: {_id: "miss"}, update: {$inc: {y: 1}}, upsert: true});
|
|
assert.commandWorked(cmdRes);
|
|
assert("value" in cmdRes);
|
|
assert.eq(null, cmdRes.value);
|
|
|
|
cmdRes = db.runCommand({
|
|
findAndModify: t.getName(),
|
|
query: {_id: "missagain"},
|
|
update: {$inc: {y: 1}},
|
|
upsert: true,
|
|
new: true
|
|
});
|
|
assert.commandWorked(cmdRes);
|
|
assert("value" in cmdRes);
|
|
assert.eq("missagain", cmdRes.value._id);
|
|
|
|
// Two upserts should have happened.
|
|
assert.eq(2, t.count());
|