Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find and Upsert Using the Java Driver

I'm trying to migrate code from the old MongoDB driver to the latest version. In the old version we had something like this:

BasicDBObject query = new BasicDBObject("foo", "foo");
int value = 1;
BasicDBObject field = new BasicDBObject("seq", value);
BasicDBObject update = new BasicDBObject("$inc", field);
DBObject o = getDBCollection().findAndModify(query, null, null, false, update, true, true);

If the 'foo' document did not exist then it would be created. If it did exist the value of seq would be incremented.

From what I can determine to do the same thing using MongoCollection I need to use replaceOne and do something like this:

Document query = new Document("foo", "foo");
int value = 1;
Document field = new Document("seq", value);
Document update = new Document("$inc", field);
UpdateOptions options = new UpdateOptions().upsert(true);
UpdateResult ret = getMongoCollection().replaceOne(query, update, options);

but this gives java.lang.IllegalArgumentException: Invalid BSON field name $inc

like image 548
David Tong Avatar asked Dec 18 '25 05:12

David Tong


1 Answers

Nope. You want .findOneAndUpdate():

FindOneAndUpdateOptions options = new FindOneAndUpdateOptions()
    .upsert(true)
    .returnDocument(ReturnDocument.AFTER);

UpdateResult ret = getMongoCollection().findOneAndUpdate(query, update, options);

The .replaceOne() means exactly that and "replaces" the entire document ( except the _id ) with the content provided. That means modifiers like $inc are not allowed here.

So you use .findOneAndUpdate() instead. Note that you likely want ReturnDocument.AFTER to return the "modified" document rather than the "original" document before the update was applied, which would be the default action.

like image 145
Blakes Seven Avatar answered Dec 20 '25 22:12

Blakes Seven