Search code examples
mongodbmongodb-querymongodb-java

Using $set and $setOnInsert during upsert


I'm trying to update a collection in mongodb and if a field exists, will insert it. I'm not so sure how can I do that with the upsert option.

MongoCollection<Document> docs = mongoDb.getCollection("users");
Bson filterQuery = new Document("userId", userId).append("fileType", fileType);
Bson updateQuery = new Document("$set", new Document("fileType", fileType).append("fileName", fileName).append("fileSize", fileSize).append("userId", userId).append("lastModifiedTimestamp", new Timestamp(System.currentTimeMillis())));
updateQuery.append("$setOnInsert", new Document("creationTimestamp", new Timestamp(System.currentTimeMillis())));
docs.updateOne(filterQuery, updateQuery, (new UpdateOptions()).upsert(true));

This is not working. I'm not updating the same fields for $set and $setOnInsert but not sure why this isn't working. Any thoughts?


Solution

  • Tried to use the following config, I have some compilation errors in your code that I fix below.

    public class StackOverflowApp {
    
       public static void main (String[] args){
    
        MongoClientOptions options = MongoClientOptions.builder().connectionsPerHost(100).build();
        MongoClient client = new MongoClient(new ServerAddress(), options);
        MongoDatabase db = client.getDatabase("test").withReadPreference(ReadPreference.secondary());
    
        String userId = "myUser2";
        String fileType = "fileType2";
        String fileName = "fileName";
        String fileSize = "fileSize";
        MongoCollection<Document> docs = db.getCollection("users");
        Bson filterQuery = new Document("userId", userId).append("fileType", fileType);
        Bson updateQuery = new Document("$set", new Document("fileType", fileType).append("fileName", fileName).append("fileSize", fileSize).append("userId", userId).append("lastModifiedTimestamp", new Date(System.currentTimeMillis())));
        ((Document)updateQuery).append("$setOnInsert", new Document("creationTimestamp", new Date(System.currentTimeMillis())));
        docs.updateOne(filterQuery, updateQuery, (new UpdateOptions()).upsert(true));
        }
    }
    

    If I run the first time I insert this one.

    "_id" : ObjectId("570c6f2105c7937ac1c794cb"),
    "fileType" : "fileType2",
    "userId" : "myUser2",
    "fileName" : "fileName",
    "fileSize" : "fileSize",
    "lastModifiedTimestamp" : ISODate("2016-04-12T03:44:33.454Z"),
    "creationTimestamp" : ISODate("2016-04-12T03:44:33.454Z")
    

    Second time only lastModifiedTimestamp is updated

    "_id" : ObjectId("570c6f2105c7937ac1c794cb"),
    "fileType" : "fileType2",
    "userId" : "myUser2",
    "fileName" : "fileName",
    "fileSize" : "fileSize",
    "lastModifiedTimestamp" : ISODate("2016-04-12T03:44:59.947Z"),
    "creationTimestamp" : ISODate("2016-04-12T03:44:33.454Z")
    

    I think that is what you were tried to achieve.