jstests/sharding/libs/update_shard_key_helpers.js
// Shard key updates are allowed in bulk ops if the update doesn't cause the doc to move shards
Shard key updates are allowed in bulk ops if the update doesn't cause the doc to move shards
Shard key updates are allowed in bulk ops if the update doesn ' t cause the doc to move shards
function assertCanUpdateInBulkOpWhenDocsRemainOnSameShard(
    st, kDbName, ns, session, sessionDB, inTxn, ordered) {
    let bulkOp;
    let bulkRes;
    let docsToInsert = [{"x": 4, "a": 3}, {"x": 100}, {"x": 300, "a": 3}, {"x": 500, "a": 6}];
    shardCollectionMoveChunks(st, kDbName, ns, {"x": 1}, docsToInsert, {"x": 100}, {"x": 300});
    if (inTxn) {
        session.startTransaction();
    }
    if (ordered) {
        bulkOp = sessionDB.foo.initializeOrderedBulkOp();
    } else {
        bulkOp = sessionDB.foo.initializeUnorderedBulkOp();
    }
    bulkOp.find({"x": 300}).updateOne({"$set": {"x": 600}});
    bulkOp.find({"x": 4}).updateOne({"$set": {"x": 30}});
    bulkRes = bulkOp.execute();
    assert.commandWorked(bulkRes);
    if (inTxn) {
        assert.commandWorked(session.commitTransaction_forTesting());
    }
    assert.eq(0, sessionDB.foo.find({"x": 300}).itcount());
    assert.eq(1, sessionDB.foo.find({"x": 600}).itcount());
    assert.eq(0, sessionDB.foo.find({"x": 4}).itcount());
    assert.eq(1, sessionDB.foo.find({"x": 30}).itcount());
    assert.eq(0, bulkRes.nUpserted);
    assert.eq(2, bulkRes.nMatched);
    assert.eq(2, bulkRes.nModified);
    sessionDB.foo.drop();
    shardCollectionMoveChunks(st, kDbName, ns, {"x": 1}, docsToInsert, {"x": 100}, {"x": 300});
    if (inTxn) {
        session.startTransaction();
    }
    if (ordered) {
        bulkOp = sessionDB.foo.initializeOrderedBulkOp();
    } else {
        bulkOp = sessionDB.foo.initializeUnorderedBulkOp();
    }
    bulkOp.find({"x": 500}).updateOne({"$inc": {"a": 1}});
    bulkOp.find({"x": 500}).updateOne({"$set": {"x": 400}});
    bulkRes = bulkOp.execute();
    assert.commandWorked(bulkRes);
    if (inTxn) {
        assert.commandWorked(session.commitTransaction_forTesting());
    }
    assert.eq(0, sessionDB.foo.find({"x": 500}).itcount());
    assert.eq(1, sessionDB.foo.find({"x": 400}).itcount());
    assert.eq(1, sessionDB.foo.find({"x": 400, "a": 7}).itcount());
    assert.eq(0, bulkRes.nUpserted);
    assert.eq(2, bulkRes.nMatched);
    assert.eq(2, bulkRes.nModified);
    sessionDB.foo.drop();
    shardCollectionMoveChunks(st, kDbName, ns, {"x": 1}, docsToInsert, {"x": 100}, {"x": 300});
    if (inTxn) {
        session.startTransaction();
    }
    if (ordered) {
        bulkOp = sessionDB.foo.initializeOrderedBulkOp();
    } else {
        bulkOp = sessionDB.foo.initializeUnorderedBulkOp();
    }
    bulkOp.find({"x": 500}).updateOne({"x": 400, "a": 6});
    bulkOp.find({"x": 500}).updateOne({"$inc": {"a": 1}});
    bulkOp.insert({"x": 1, "a": 1});
    bulkOp.find({"x": 400}).updateOne({"$set": {"x": 600}});
    bulkRes = bulkOp.execute();
    assert.commandWorked(bulkRes);
    if (inTxn) {
        assert.commandWorked(session.commitTransaction_forTesting());
    }
    assert.eq(0, sessionDB.foo.find({"x": 500}).itcount());
    assert.eq(0, sessionDB.foo.find({"x": 400}).itcount());
    assert.eq(1, sessionDB.foo.find({"x": 600}).itcount());
    assert.eq(1, sessionDB.foo.find({"x": 600, "a": 6}).itcount());
    assert.eq(1, sessionDB.foo.find({"x": 1}).itcount());
    assert.eq(0, bulkRes.nUpserted);
    assert.eq(2, bulkRes.nMatched);
    assert.eq(2, bulkRes.nModified);
    assert.eq(1, bulkRes.nInserted);
    sessionDB.foo.drop();
}
function assertCanUpdateInBulkOpWhenDocsRemainOnSameShard ( st , kDbName , ns , session , sessionDB , inTxn , ordered ) { let bulkOp ; let bulkRes ; let docsToInsert = [ { "x" : 4 , "a" : 3 } , { "x" : 100 } , { "x" : 300 , "a" : 3 } , { "x" : 500 , "a" : 6 } ] ; shardCollectionMoveChunks ( st , kDbName , ns , { "x" : 1 } , docsToInsert , { "x" : 100 } , { "x" : 300 } ) ; if ( inTxn ) { session . startTransaction ( ) ; } if ( ordered ) { bulkOp = sessionDB . foo . initializeOrderedBulkOp ( ) ; } else { bulkOp = sessionDB . foo . initializeUnorderedBulkOp ( ) ; } bulkOp . find ( { "x" : 300 } ) . updateOne ( { "$set" : { "x" : 600 } } ) ; bulkOp . find ( { "x" : 4 } ) . updateOne ( { "$set" : { "x" : 30 } } ) ; bulkRes = bulkOp . execute ( ) ; assert . commandWorked ( bulkRes ) ; if ( inTxn ) { assert . commandWorked ( session . commitTransaction_forTesting ( ) ) ; } assert . eq ( 0 , sessionDB . foo . find ( { "x" : 300 } ) . itcount ( ) ) ; assert . eq ( 1 , sessionDB . foo . find ( { "x" : 600 } ) . itcount ( ) ) ; assert . eq ( 0 , sessionDB . foo . find ( { "x" : 4 } ) . itcount ( ) ) ; assert . eq ( 1 , sessionDB . foo . find ( { "x" : 30 } ) . itcount ( ) ) ; assert . eq ( 0 , bulkRes . nUpserted ) ; assert . eq ( 2 , bulkRes . nMatched ) ; assert . eq ( 2 , bulkRes . nModified ) ; sessionDB . foo . drop ( ) ; shardCollectionMoveChunks ( st , kDbName , ns , { "x" : 1 } , docsToInsert , { "x" : 100 } , { "x" : 300 } ) ; if ( inTxn ) { session . startTransaction ( ) ; } if ( ordered ) { bulkOp = sessionDB . foo . initializeOrderedBulkOp ( ) ; } else { bulkOp = sessionDB . foo . initializeUnorderedBulkOp ( ) ; } bulkOp . find ( { "x" : 500 } ) . updateOne ( { "$inc" : { "a" : 1 } } ) ; bulkOp . find ( { "x" : 500 } ) . updateOne ( { "$set" : { "x" : 400 } } ) ; bulkRes = bulkOp . execute ( ) ; assert . commandWorked ( bulkRes ) ; if ( inTxn ) { assert . commandWorked ( session . commitTransaction_forTesting ( ) ) ; } assert . eq ( 0 , sessionDB . foo . find ( { "x" : 500 } ) . itcount ( ) ) ; assert . eq ( 1 , sessionDB . foo . find ( { "x" : 400 } ) . itcount ( ) ) ; assert . eq ( 1 , sessionDB . foo . find ( { "x" : 400 , "a" : 7 } ) . itcount ( ) ) ; assert . eq ( 0 , bulkRes . nUpserted ) ; assert . eq ( 2 , bulkRes . nMatched ) ; assert . eq ( 2 , bulkRes . nModified ) ; sessionDB . foo . drop ( ) ; shardCollectionMoveChunks ( st , kDbName , ns , { "x" : 1 } , docsToInsert , { "x" : 100 } , { "x" : 300 } ) ; if ( inTxn ) { session . startTransaction ( ) ; } if ( ordered ) { bulkOp = sessionDB . foo . initializeOrderedBulkOp ( ) ; } else { bulkOp = sessionDB . foo . initializeUnorderedBulkOp ( ) ; } bulkOp . find ( { "x" : 500 } ) . updateOne ( { "x" : 400 , "a" : 6 } ) ; bulkOp . find ( { "x" : 500 } ) . updateOne ( { "$inc" : { "a" : 1 } } ) ; bulkOp . insert ( { "x" : 1 , "a" : 1 } ) ; bulkOp . find ( { "x" : 400 } ) . updateOne ( { "$set" : { "x" : 600 } } ) ; bulkRes = bulkOp . execute ( ) ; assert . commandWorked ( bulkRes ) ; if ( inTxn ) { assert . commandWorked ( session . commitTransaction_forTesting ( ) ) ; } assert . eq ( 0 , sessionDB . foo . find ( { "x" : 500 } ) . itcount ( ) ) ; assert . eq ( 0 , sessionDB . foo . find ( { "x" : 400 } ) . itcount ( ) ) ; assert . eq ( 1 , sessionDB . foo . find ( { "x" : 600 } ) . itcount ( ) ) ; assert . eq ( 1 , sessionDB . foo . find ( { "x" : 600 , "a" : 6 } ) . itcount ( ) ) ; assert . eq ( 1 , sessionDB . foo . find ( { "x" : 1 } ) . itcount ( ) ) ; assert . eq ( 0 , bulkRes . nUpserted ) ; assert . eq ( 2 , bulkRes . nMatched ) ; assert . eq ( 2 , bulkRes . nModified ) ; assert . eq ( 1 , bulkRes . nInserted ) ; sessionDB . foo . drop ( ) ; }
Shard key updates are allowed in bulk ops if the update doesn't cause the doc to move shards
Shard key updates are allowed in bulk ops if the update doesn ' t cause the doc to move shards
// Update multiple documents on different shards // Check that final doc is correct after doing $inc on doc A and then updating the shard key // for doc A. The outcome should be the same for both ordered and unordered bulk ops because // the doc will not change shards, so both udpates will be targeted to the same shard. // Check that updating the shard key for doc A, then doing $inc on the old doc A does not // inc the field on the final doc. The outcome should be the same for both ordered and // unordered bulk ops because the doc will not change shards, so both udpates will be // targeted to the same shard.