Весеннее массовое обновление данных mongo

Массовые обновления поддерживаются из spring-data-mongodb начиная с 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 имеет функцию с именем void save(Object objectToSave); Я хочу вставить/обновить всю запись, а не отдельные поля. Есть ли способ или функция, с помощью которой я могу аннулировать класс Update?

Может как-то так..?

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

person Shuying Zhang    schedule 17.11.2016    source источник


Ответы (4)


Похоже, что upsert(Query query, Object object) не поддерживается в массовых операциях Spring Data MongoDB.

Однако мы можем использовать метод Update.fromDBObject для создания объекта Update из 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();
person Amalia Neag    schedule 01.03.2017

Вы можете попробовать это:

BulkOperations ops = mongoOps.bulkOps(BulkMode.<ordered/unordered>,<your ob>.class);
loop on your batch {
    Update update = Update.fromDBObject(
        BasicDBObjectBuilder.start("$set", <your ob>).get()
    );
    ops.upsert(query(where("").is(<your ob>.something())), update);
}
ops.execute();

Это обновит все pojo (а не некоторые конкретные поля), как и сохранить.

person Amber Kulkarni    schedule 21.08.2017

Удалить и вставить будет вариант, который вы можете выбрать, но вам необходимо сделать резервную копию ваших данных, прежде чем вы выберете этот вариант в случае каких-либо сбоев.

person Sunand Padmanabhan    schedule 05.02.2017
comment
Ужасная идея. Очень легко оказаться в противоречивом состоянии. - person SouvikMaji; 11.08.2020

org.springframework.data.mongodb.core.MongoTemplate обеспечивает реализацию BulkWriteOperation. Вы можете использовать его.

BulkWriteOperation bulkWriteOperation= mongoTemplate.getCollection(collectionName).initializeUnorderedBulkOperation();
person Yusuf Malkan    schedule 10.07.2019