Spring data mongo bulk update

Shuying Zhang picture Shuying Zhang · Nov 17, 2016 · Viewed 9.2k times · Source

Bulk updates are supported from spring-data-mongodb from 1.9.0.RELEASE.

BulkOperations ops = template.bulkOps(BulkMode.UNORDERED, Match.class);
for (User user : users) {
    Update update = new Update();
    ...
    ops.updateOne(query(where("id").is(user.getId())), update);
}
ops.execute();

mongoTemplate has the function called void save(Object objectToSave); I want to insert/update the whole record but not some particular fields. Is there any way or function that I can void the Update class?

Maybe something like this..?

BulkOperations ops = template.bulkOps(BulkMode.UNORDERED, Match.class);
for (User user : users) {
    ...
    ops.save(query(where("id").is(user.getId())), user);
}
ops.execute();

Answer

Amalia Neag picture Amalia Neag · Mar 1, 2017

It seems that the upsert(Query query, Object object) it is not supported in the Spring Data MongoDB bulk operations.

However we can use Update.fromDBObject method to generate an Update object from a DBObject:

    BulkOperations bulkOps = mongoOperations.bulkOps(BulkOperations.BulkMode.ORDERED, entityInformation.getJavaType()); 

    // add "save" operation for each entity
    MongoConverter converter = mongoOperations.getConverter();
    ConversionService conversionService = converter.getConversionService();
    com.mongodb.DBObject dbObject;
    for (S entity : entities) {
        if (entityInformation.isNew(entity)) { // --- if NEW entity, then generate id and INSERT ---

            // generate NEW id
            ID id = conversionService.convert(new ObjectId(), entityInformation.getIdType());                
            entity.setId(id);
            // insert
            bulkOps.insert(entity);

        } else { // --- if EXISTING entity, then UPSERT ---

            // convert entity to mongo DBObject
            dbObject = new BasicDBObject();
            // NULL fields will NOT BE UPDATED - will be ignored when converting an entity to a {@link com.mongodb.DBObject} 
            // and thus they will not be added to the {@link Update} statement.
            converter.write(entity, dbObject);                
            // upsert
            bulkOps.upsert(new Query(Criteria.where(UNDERSCORE_ID).is(dbObject.get(UNDERSCORE_ID))),
                           Update.fromDBObject(new BasicDBObject("$set", dbObject)));
        }
    }
    // execute bulk operations
    bulkOps.execute();