最近使用mongodb實現一個需求,需要批量處理數據,並且存在則修改,不存在則添加,updateMany方法,無法達到要求,經查,發現mongodb中存在一個BulkWrite方法可以實現該需求,該操作可實現類似於mysql的insert into ... on duplicate key udpdate ...
使用如下命令創建用於測試的db和collection以及添加index並查看
use mockdb db.mockcoll.createIndex({"flag":1}) db.mockcoll.getIndexes()
mockcoll中只存在一個字段flag,並在該字段建立唯一索引
下面為代碼示例
public interface MongoCons { String mockdbName = "mockdb"; String mockcollName = "mockcoll"; static MongoCollection<Document> getCollection(MongoTemplate mongoTemplate){ MongoDatabase mongoDatabase = mongoTemplate.getMongoDbFactory().getMongoDatabase(mockdbName); MongoCollection<Document> collection = mongoDatabase.getCollection(mockcollName); return collection; } }
@Component public class MongoBulkDao { private Logger logger = LoggerFactory.getLogger(MongoBulkDao.class); @Autowired private MongoTemplate mongoTemplate; public void addOrUpdate(List<String> dataList) { try { MongoCollection<Document> collection = MongoCons.getCollection(mongoTemplate); List<WriteModel<Document>> list = new ArrayList<>(); UpdateOptions upsert = new UpdateOptions().upsert(true); Iterator<String> iterator = dataList.iterator(); String next = null; while (iterator.hasNext()) { next = iterator.next(); BasicDBObject filter = new BasicDBObject().append("flag", next); BasicDBObject update = new BasicDBObject().append("$set", new BasicDBObject().append("flag", next)); UpdateOneModel<Document> um = new UpdateOneModel<Document>(filter, update, upsert); list.add(um); // 刪除掉不需要的數據 iterator.remove(); } collection.bulkWrite(list, new BulkWriteOptions().ordered(false)); } catch (Exception e) { logger.error("", e); } } }
上述代碼那種調用了bulkWrite的其中一個構造方法,new BulkWriteOptions().ordered(false)中orderd默認為ture,即如果其中一條執行錯誤,后面的將不再執行,為false,其中的一條執行錯誤,跳過去,繼續執行下面的命令。