David Tong
David Tong

Reputation: 101

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

Upvotes: 3

Views: 2269

Answers (1)

Blakes Seven
Blakes Seven

Reputation: 50406

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.

Upvotes: 4

Related Questions