21
votes

How can I upsert data into mongodb collection with java-driver?

I try (with empty collection):

db.getCollection(collection).update(new BasicDBObject("_id", "12"), dbobject, true, false);

But document was created with _id == ObjectID(...). Not with "12" value.

This code (js) add document with _id = "12" as expected

db.metaclass.update(
   { _id:12},
   {
     $set: {b:1}
   },
   { upsert: true }
)

mongo-java-driver-2.11.2

4

4 Answers

18
votes

You cannot set _id if dbobject is just a document and does not contain an update operator eg: $set, $setOnInsert.

Just passing a document will replace the whole document meaning it doesn't set an _id a falls back to ObjectId

So your example works if you use an update operator eg:

db.getCollection(collection).update(
    new BasicDBObject("_id", "12"), 
    new BasicDBObject("$set", new BasicDBObject("Hi", "world")), true, false)
23
votes

If you are using mongo-java driver 3, following .updateOne() method with {upsert, true} flag works.

 void setLastIndex(MongoClient mongo, Long id, Long lastIndexValue) {

    Bson filter = Filters.eq("_id", id);

    Bson update =  new Document("$set",
                  new Document()
                        .append("lastIndex", lastIndexValue)
                        .append("created", new Date()));
    UpdateOptions options = new UpdateOptions().upsert(true);

    mongo.getDatabase(EventStreamApp.EVENTS_DB)
         .getCollection(EventCursor.name)
         .updateOne(filter, update, options);
  }
3
votes

You can use the replaceOne method and specify the ReplaceOptions (since 3.7) :

private static final ReplaceOptions REPLACE_OPTIONS
      = ReplaceOptions.createReplaceOptions(new UpdateOptions().upsert(true));  

db.getCollection(collection).replaceOne(new BasicDBObject("_id", "12"), dbobject, REPLACE_OPTIONS);

For older versions you can directly pass the UpdateOptions to the replaceOne method :

private static final UpdateOptions UPDATE_POLICY = new UpdateOptions().upsert(true);
db.getCollection(collection).replaceOne(new BasicDBObject("_id", "12"), dbobject, UPDATE_POLICY);  

As mentioned in the documentation :

replaceOne() replaces the first matching document in the collection that matches the filter, using the replacement document.

If upsert: true and no documents match the filter, replaceOne() creates a new document based on the replacement document.

-1
votes
This is to upsert with scala driver which i couldnot find in web

con.updateOne(  
            equal("vendor_id", vendorId),          
            inc("views_count", f.views),
            UpdateOptions().upsert(true)) 

to do so import the following
import org.mongodb.scala.model.UpdateOptions