3

I want to update multiple rows in My Collection called "Users". Right now I am updating both the rows seperately but I want to do the same in one query.

My current code:

coll.update(new BasicDBObject().append("key", k1), new BasicDBObject().append("$inc", new BasicDBObject().append("balance", 10)));              
coll.update(new BasicDBObject().append("key", k2), new BasicDBObject().append("$inc", new BasicDBObject().append("balance", -10)));

How to make these two seperate updates in one statement?

2 Answers 2

3

First let me translate your java code to shell script so people can read it :

db.coll.update({key: k1}, {$inc:{balance:10}})
db.coll.update({key: k2}, {$inc:{balance:-10}})

Now, the reason you will never be able to do this in one update is because there is no way to provide a unique update clause per matching document. You could bulk your updates so that you can do this (pseudoish):

set1 = getAllKeysForBalanceIncrease();
set2 = getAllKeysForBalanceDecrease();

db.coll.update({key:{$in:set1}}, {$inc:{balance:10}}, false, true)
db.coll.update({key:{$in:set2}}, {$inc:{balance:-10}}, false, true)

In other words, you can update multiple documents within one atomic write but the update operation will be static for all documents. So aggregating all documents that require the same update is your only optimization path.

The $in clause can be composed in Java through :

ObjectId[] oidArray = getAllKeysEtc();
query = new BasicDBObject("key", new BasicDBObject("$in", oidArray));
Sign up to request clarification or add additional context in comments.

Comments

-1

In MongoDB you do not have transactions that span multiple documents. Only writes on a document are atomic. But you can do updates with:

public WriteResult update(DBObject q,
                      DBObject o,
                      boolean upsert,
                      boolean multi)

But note, this will not be in a transaction.

1 Comment

(I didn't downvote, but if I had to guess--) narrowing the time spent within a transaction is certainly one reason to send updates in a batch. But another reason is to increase throughput. First, batches allow the amortization of overhead over the number of records in the batch. Second, if the driver one is working with is not asynchronous, batching circumvents the latency cost of waiting for an ACK for each update.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.