batch updates

6 views
Skip to first unread message

Lincoln

unread,
Aug 13, 2009, 11:37:50 PM8/13/09
to mongod...@googlegroups.com
Hey guys, 

Is there any way to send a batch of updates to the same document via the Java driver in a single call?

I have a document with 3 fields I want to update - 1 data field and 2 counters.  I've been trying to create an update DBObject and continue calling add() on it but not only does this not seem to work, I start getting the following exception when I try to call toString on it:

java.lang.RuntimeException: can't serialize type : class java.util.HashMap
        at com.mongodb.util.JSON.serialize(JSON.java:128)
        at com.mongodb.util.JSON.serialize(JSON.java:108)
        at com.mongodb.util.JSON.serialize(JSON.java:32)
        at com.mongodb.BasicDBObject.toString(BasicDBObject.java:192)

Very weird stuff.  Please let me know if I'm just going about this wrong.  If it's not obvious I can send along an illustrative example.

Thanks,
Lincoln

Eliot Horowitz

unread,
Aug 14, 2009, 1:44:46 AM8/14/09
to mongod...@googlegroups.com
Can you send the code you're using? I think this should work in theory...

Lincoln

unread,
Aug 14, 2009, 2:16:33 AM8/14/09
to mongod...@googlegroups.com
Hey,

After testing some more it actually seems like it's executing the $set and the last $inc but not the middle $inc.  I guess BasicDBObject is backed by a hash so I'm overwriting the $inc key.  Is there a way to batch multiple $incs?

Here's the (pseudo) code:

import com.mongodb._
import com.mongodb.{BasicDBObject => DBO}

val query = new DBO("_id", user.id.objectId)
val update = new DBO("$set", new DBO("status", user.status))
update.append("$inc", new DBO("stats.total", 1))
update.append("$inc", new DBO("stats.type", 1))
mongo.getCollection("users").update(query, update, true, false)

Also, any thoughts on why calling update.toString throws that exception I mentioned?  That's almost bugging me more than the $inc because it's preventing me from logging my update.

Thanks,
Lincoln

Dwight Merriman

unread,
Aug 14, 2009, 9:17:00 AM8/14/09
to google groups, Lincoln
Hi,

I think you need to put both of the $inc’s inside a single $inc object.  Here is an example from the mongo shell (I don’t know the java driver well):

~/mongo ./mongo
> t = db.bar
test.bar

> t.save( { name : 'joe' } )

> t.update({}, {$set : { status : 2 }, $inc : { total : 1, type : 1 }} );

> t.findOne()
{"_id" :  ObjectId( "4a8562dff14fa07f46a382d9")  , "name" : "joe" , "status" : 2 , "total" : 1 , "type" : 1}

> t.update({}, {$set : { status : 2 }, $inc : { total : 1, type : 1 }} );

> t.findOne()
{"_id" :  ObjectId( "4a8562dff14fa07f46a382d9")  , "name" : "joe" , "status" : 2 , "total" : 2 , "type" : 2}

Lincoln

unread,
Aug 14, 2009, 12:56:21 PM8/14/09
to Dwight Merriman, google groups
OK thanks, I'll give that a try.  

Lincoln

unread,
Aug 14, 2009, 2:00:54 PM8/14/09
to Dwight Merriman, google groups
Awesome, that fixed it.

In the java driver it looks like this:

val update = new DBO("$inc", new DBO("total", 1).append("text", 1))

Thanks,
Lincoln
Reply all
Reply to author
Forward
0 new messages