2019-05-20 23:25:33 +02:00
|
|
|
// Tests for $merge with a non-existing target collection.
|
|
|
|
(function() {
|
|
|
|
"use strict";
|
|
|
|
|
2019-06-06 15:50:27 +02:00
|
|
|
load("jstests/aggregation/extras/merge_helpers.js"); // For withEachMergeMode.
|
|
|
|
load("jstests/aggregation/extras/utils.js"); // For assertErrorCode.
|
2019-05-20 23:25:33 +02:00
|
|
|
|
|
|
|
const st = new ShardingTest({shards: 2, rs: {nodes: 1}, config: 1});
|
|
|
|
const sourceDB = st.s0.getDB("source_db");
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Run an aggregation on 'sourceColl' that writes documents to 'targetColl' with $merge.
|
|
|
|
*/
|
|
|
|
function testMerge(sourceColl, targetColl, shardedSource) {
|
|
|
|
sourceColl.drop();
|
|
|
|
|
|
|
|
if (shardedSource) {
|
|
|
|
st.shardColl(sourceColl, {_id: 1}, {_id: 0}, {_id: 1}, sourceDB.getName());
|
|
|
|
}
|
|
|
|
|
|
|
|
for (let i = 0; i < 10; i++) {
|
|
|
|
assert.commandWorked(sourceColl.insert({_id: i}));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test the behavior for each of the $merge modes. Since the target collection does not
|
|
|
|
// exist, the behavior should be identical.
|
|
|
|
withEachMergeMode(({whenMatchedMode, whenNotMatchedMode}) => {
|
|
|
|
// Skip the combination of merge modes which will fail depending on the contents of the
|
|
|
|
// source and target collection, as this will cause the assertion below to trip.
|
|
|
|
if (whenMatchedMode == "fail" || whenNotMatchedMode == "fail")
|
|
|
|
return;
|
|
|
|
|
|
|
|
targetColl.drop();
|
|
|
|
sourceColl.aggregate([{
|
|
|
|
$merge: {
|
|
|
|
into: {db: targetColl.getDB().getName(), coll: targetColl.getName()},
|
|
|
|
whenMatched: whenMatchedMode,
|
2019-05-22 19:45:47 +02:00
|
|
|
whenNotMatched: whenNotMatchedMode,
|
|
|
|
on: "_id"
|
2019-05-20 23:25:33 +02:00
|
|
|
}
|
|
|
|
}]);
|
|
|
|
assert.eq(whenNotMatchedMode == "discard" ? 0 : 10, targetColl.find().itcount());
|
|
|
|
});
|
|
|
|
|
2019-05-22 19:45:47 +02:00
|
|
|
// Test that $merge fails if the "on" field is anything but "_id" when the target collection
|
|
|
|
// does not exist.
|
|
|
|
withEachMergeMode(({whenMatchedMode, whenNotMatchedMode}) => {
|
|
|
|
// Skip the combination of merge modes which will fail depending on the contents of the
|
|
|
|
// source and target collection, as this will cause the assertion below to trip.
|
|
|
|
if (whenMatchedMode == "fail" || whenNotMatchedMode == "fail")
|
|
|
|
return;
|
|
|
|
|
|
|
|
targetColl.drop();
|
|
|
|
assertErrorCode(
|
|
|
|
sourceColl,
|
|
|
|
[{
|
|
|
|
$merge: {
|
|
|
|
into: {db: targetColl.getDB().getName(), coll: targetColl.getName()},
|
|
|
|
whenMatched: whenMatchedMode,
|
|
|
|
whenNotMatched: whenNotMatchedMode,
|
|
|
|
on: "not_allowed"
|
|
|
|
}
|
|
|
|
}],
|
|
|
|
51190);
|
|
|
|
});
|
|
|
|
|
2019-05-20 23:25:33 +02:00
|
|
|
// If 'targetColl' is in the same database as 'sourceColl', test that the legacy $out works
|
|
|
|
// correctly.
|
|
|
|
if (targetColl.getDB() == sourceColl.getDB()) {
|
|
|
|
jsTestLog(
|
|
|
|
`Testing $out from ${sourceColl.getFullName()} ` +
|
|
|
|
`(${shardedSource ? "sharded" : "unsharded"}) to ${targetColl.getFullName()} ` +
|
|
|
|
`with legacy syntax`);
|
|
|
|
|
|
|
|
targetColl.drop();
|
|
|
|
sourceColl.aggregate([{$out: targetColl.getName()}]);
|
|
|
|
assert.eq(10, targetColl.find().itcount());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const sourceColl = sourceDB["source_coll"];
|
|
|
|
const outputCollSameDb = sourceDB["output_coll"];
|
|
|
|
|
|
|
|
// Test $merge from an unsharded source collection to a non-existent output collection in the
|
|
|
|
// same database.
|
|
|
|
testMerge(sourceColl, outputCollSameDb, false);
|
|
|
|
|
|
|
|
// Like the last test case, but perform a $merge from a sharded source collection to a
|
|
|
|
// non-existent output collection in the same database.
|
|
|
|
testMerge(sourceColl, outputCollSameDb, true);
|
|
|
|
|
|
|
|
// Test that $merge in a sharded cluster fails when the output is sent to a different database
|
|
|
|
// that doesn't exist.
|
|
|
|
const foreignDb = st.s0.getDB("foreign_db");
|
|
|
|
const outputCollDiffDb = foreignDb["output_coll"];
|
|
|
|
foreignDb.dropDatabase();
|
|
|
|
assert.throws(() => testMerge(sourceColl, outputCollDiffDb, false));
|
|
|
|
assert.throws(() => testMerge(sourceColl, outputCollDiffDb, true));
|
|
|
|
|
|
|
|
// Test $merge from an unsharded source collection to an output collection in a different
|
|
|
|
// database where the database exists but the collection does not.
|
|
|
|
assert.commandWorked(foreignDb["test"].insert({_id: "forcing database creation"}));
|
|
|
|
testMerge(sourceColl, outputCollDiffDb, false);
|
|
|
|
|
|
|
|
// Like the last test, but with a sharded source collection.
|
|
|
|
testMerge(sourceColl, outputCollDiffDb, true);
|
|
|
|
st.stop();
|
|
|
|
}());
|