【问题标题】:Spring data mongo bulk updateSpring数据mongodb批量更新
【发布时间】:2016-11-17 03:48:03
【问题描述】:

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();

【问题讨论】:

    标签: mongotemplate


    【解决方案1】:

    你可以试试这个:

    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(不是某些特定字段)。

    【讨论】:

      【解决方案2】:

      Spring Data MongoDB 批量操作中似乎不支持 upsert(Query query, Object object)

      但是我们可以使用 Update.fromDBObject 方法从 DBObject 生成 Update 对象:

          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();
      

      【讨论】:

        【解决方案3】:

        org.springframework.data.mongodb.core.MongoTemplate 提供了 BulkWriteOperation 的实现。你可以使用它。

        BulkWriteOperation bulkWriteOperation= mongoTemplate.getCollection(collectionName).initializeUnorderedBulkOperation();
        

        【讨论】:

          【解决方案4】:
              BulkOperations bulkOperations = mongoTemplate.bulkOps(BulkOperations.BulkMode.UNORDERED, "someCollection");
              bulkOperations.insert(addressRanges);
              bulkOperations.execute();
          

          这就是你所需要的。

          【讨论】:

            【解决方案5】:

            删除和插入将是您可以选择的选项,但您需要在选择此选项之前备份您的数据,以防出现任何故障。

            【讨论】:

            • 糟糕的想法。很容易陷入不一致的状态。
            猜你喜欢
            • 2017-05-13
            • 1970-01-01
            • 2021-03-21
            • 1970-01-01
            • 1970-01-01
            • 2011-05-25
            • 2013-06-18
            • 1970-01-01
            • 2019-05-02
            相关资源
            最近更新 更多