Search code examples
javamongodbatomicdatabase

How do I perform atomic updates of fields of a MongoDB document?


Disclaimer: I'm a noob to Mongo and to databases in general, so if I'm off on terminology or concepts please let me know.

For the purposes of this example, I'd like to store the mouse coordinates together within an object nested within a document. That document would look something like:

{ "_id" : ObjectId("4f39805d35919a2a7c7aba3e"), "mouseLoc" : { "x" : 10, "y" : 20 } }

It seems like atomic updating, via modifier operations, is the way to go, as I'm only storing values here (retrieving them elsewhere, in other software). However, I can't figure out the query part. How do I access this document in order to set the x and y values?

I'm using Java, so I'm currently trying:

BasicDBObject mouseLoc = new BasicDBObject();
mouseLoc.put("x", mouseX);
mouseLoc.put("y", mouseY);
myCollection.update(queryObj, new BasicDBObject("$set", mouseLoc), true, false);

However, I don't know how to specify that queryObj to get the document with the mouseLoc key. Alternatively, if there's a smarter way to store information like this, please school me.

I can follow along with Mongo shell/JS tips if that's simpler.


UPDATE:
I can query for this document if I give it a static field like 'name'. So, to update this document:

{ "_id" : ObjectId("4f39805d35919a2a7c7aba3e"), "name" : "mouseLoc", "mouseLoc" : { "x" : 10, "y" : 20 } }

I can use this code:

BasicDBObject mouseLoc = new BasicDBObject();
mouseLoc.put("x", mouseX);
mouseLoc.put("y", mouseY);

BasicDBObject queryObj = new BasicDBObject("name", "mouseLoc");
BasicDBObject updateObj = new BasicDBObject("$set", new BasicDBObject("mouseLoc", mouseLoc));

myCollection.update(queryObj, updateObj, true, false);

However, it seems redundant to have to specify that "name" field just to be able to retrieve the document with the "mouseLoc" key. Maybe I'm just misunderstanding database / mongo design?


Solution

  • The query part is where you specify a way to find you document, e.g: the _id or another unique field.

    In your example, it will look like this:

    ObjectId objectId = new ObjectId("4f39805d35919a2a7c7aba3e");
    BasicDBObject queryObj = new BasicDBObject("_id", objectId);
    

    (Maybe there's something missing about ObjectId, since I don't know Java.)

    UPDATE

    If you are searching for a specific mouseLoc, the queryObj will be the very mouseLoc object. (In JSON it would be { 'x': mouseX, 'y': mouseY }.)