SpringBoot作mongodb批量更新

最近有一个需求,需要从一个MongoDB操作日志表中取出所有对mongo集合的处理,然后执行操作。简单来说就是找到之前所有用户的操作,然后在一张空白集合中再次演绎一遍。因为这些操作基本都不相同即每次修改都是不一样的,所以从效率上考虑采用批量更新的方法。

参考文章:https://www.jianshu.com/p/3577ccb722a1
原文对批量更新的讲述比较细。由于讲述的是mongo2.0.0之前版本,而我使用的是2.1.5,故而实施过程中会出现了一些版本兼容问题:
mongoTemplate.getCollection()返回的类型由之前的 DBCollection 变成了 MongoCollection

下面给出修改后的核心代码(如有兴趣可参考尹吉欢文章 https://www.jianshu.com/p/3577ccb722a1 )。

1. 定义一个[封装更新与查询]工具类

public class BatchUpdateOptions {
	private Query query;
	private Update update;
	private boolean upsert = false;
	private boolean multi = false;
}

2. 封装一个Mongo数据访问基础对象

public class MongoBaseDao {
	/**
	 * 批量更新
	 * @param ordered 如果为true,一条语句更新失败,剩下的语句将不再执。如果为false,一条语句更新失败,剩下的将继续执行。默认为true。
	 * @return
	 */
	public static int batchUpdate(MongoTemplate mongoTemplate, String collectionName, List options, boolean ordered) {
		return doBatchUpdate(mongoTemplate, collectionName, options, ordered);
	}

	private static int doBatchUpdate(MongoTemplate mongoTemplate, String collName, List options, boolean ordered) {
		DBObject command = new BasicDBObject();
		command.put("update", collName);
		List updateList = new ArrayList();
		for (BatchUpdateOptions option : options) {
			BasicDBObject update = new BasicDBObject();
			update.put("q", option.getQuery().getQueryObject());
			update.put("u", option.getUpdate().getUpdateObject());
			update.put("upsert", option.isUpsert());
			update.put("multi", option.isMulti());
			updateList.add(update);
		}
		command.put("updates", updateList);
		command.put("ordered", ordered);
		Document document = mongoTemplate.getDb().runCommand((Bson) command);
		System.out.println("doc:"+document);
		System.out.println("doc--n:"+document.get("n"));
		System.out.println("doc--nModified:"+document.get("nModified"));

		// n为符合Query查询的记录总数 因为是根据id进行的查询, 原则上只要符合查询的记录数等于要更新的数量就代表成功
		Object n = document.get("n");
		System.out.println("doc--n--class:"+n.getClass());

		if(n.getClass()==Integer.class){
			return (Integer)n;
		}
		return Integer.parseInt(String.valueOf(n));
	}
}

注意: 这里对原作者的代码进行了修改【联系到了原作者,原作者给出的方法】:

  1. 将DBObjec类型的command转换为了Bson
  2. 执行命令的函数改为了mongoTemplate.getDb().runCommand()

mongo官方手册给出的更新命令的说明:
https://docs.mongodb.com/manual/reference/command/update/

3. 调用实例

		List list = new ArrayList();
        // 注意upsert置为false, 更新过程不做插入
        for (Map map : aus) {
   
           Update update = new Update();
            for (Object k : map.keySet()
            ) {
                update.set(String.valueOf(k), map.get(k));
            }
            
            Query query = Query.query(Criteria.where(primaryKey).is(map.get("id")));
            BatchUpdateOptions options = new BatchUpdateOptions(query, update, false, true);
            list.add(options);
        }
        int n = MongoBaseDao.batchUpdate(mongoTemplate, collectionName, list, true);
        boolean res = (n == aus.size());

aus为封装的所有对mongo进行更新的集合。

你可能感兴趣的:(JAVA)