mongo批量更新的几种方法

50w数据做测试

看一下mongo支持批量更新的几种PAI

 

1.0 public UpdateResult updateMulti(Query query, UpdateDefinition update, Class<?> entityClass)



2.0public UpdateResult updateMulti(Query query, UpdateDefinition update, String collectionName)



3.0public UpdateResult updateMulti(Query query, UpdateDefinition update, Class<?> entityClass, String collectionName)

4.0

 

 

给字段phone加上了唯一索引

/**
* 电话
*/
@Indexed(unique = true)
private String phone;

 

具体写法一:
1.查询集合内所有的数据
 Query query0 = new Query();
        query0.fields().include("phone");
        long l0 = System.currentTimeMillis();
        List<User> users1 = mongoTemplate.find(query0, User.class, "animals");
        List<String> collect = users1.stream().map(User::getPhone).collect(Collectors.toList());
        long l1 = System.currentTimeMillis();
        System.out.println(">>>>>>>>>>>:"+(l1-l0));
2.更新参数

 Update update=new Update();
        update.set("sex","未知");
        update.set("email","898989@qq.com");
        update.set("work","焊武大帝");
        UpdateOptions updateOptions=new UpdateOptions();
        updateOptions.upsert(false);
        Query query = new Query();
        Criteria criteria=new Criteria();
        criteria.and("phone").in(collect);
        query.addCriteria(criteria);

3.具体更新

 long l2= System.currentTimeMillis();
 mongoTemplate.updateMulti(query, update, User.class,"animals");
long l3= System.currentTimeMillis();
 System.out.println(">>>>>>>>>>>>>>>:"+(l3-l2));

4.结果

>>>>>>>>>>>:2379(查询整个集合一个字段出来在2.5s以内)
>>>>>>>>>>>>>>>:7629(更新50w控制在8s以内)
总计在12s以内,还可以接受

 

具体写法二:
     1.0查询: Query query0 = new Query();
        query0.fields().include("phone");
        long l0 = System.currentTimeMillis();
        List<User> users1 = mongoTemplate.find(query0, User.class, "animals");
        List<String> collect =users1.stream().map(User::getPhone).collect(Collectors.toList());
        long l1 = System.currentTimeMillis();
        System.out.println(">>>>>>>>>>>:"+(l1-l0));
        Update update=new Update();
        update.set("sex","未知0");
        update.set("email","8989809@qq.com");
        update.set("work","焊武大帝0");
        UpdateOptions updateOptions=new UpdateOptions();
      2.更新参数:  updateOptions.upsert(false);
        Query query = new Query();
        Criteria criteria=new Criteria();
        criteria.and("phone").in(collect);
        query.addCriteria(criteria);
        long l2= System.currentTimeMillis();


      3.0具体执行:  BulkOperations bulkOps = mongoTemplate.bulkOps(BulkOperations.BulkMode.UNORDERED, "animals");
        bulkOps.updateMulti(query, update);

        bulkOps.execute();
        long l3= System.currentTimeMillis();
        System.out.println(">>>>>>>>>>>>>>>:"+(l3-l2));
4.0执行结果
>>>>>>>>>>>:2408(查询组织参数)
>>>>>>>>>>>>>>>:7769(50w执行)

 

具体写法三:(如果phone不加索引,会非常非常慢)
1.0  List<Pair<Query, Update>> updates=new ArrayList<>();
        collect.stream().forEach(ele->{
            Query query1 = new Query();
            query1.addCriteria(new Criteria().and("phone").is(ele));
            Update update0=new Update();
            update0.set("sex","未知");
            update0.set("email","898989@qq.com");
            update0.set("work","焊武大帝");
            Pair<Query, Update> of = Pair.of(query1, update0);
            updates.add(of);
        });
        BulkOperations bulkOps = mongoTemplate.bulkOps(BulkOperations.BulkMode.UNORDERED, "animals");


     bulkOps.updateMulti(updates);
        bulkOps.execute();
        long l3= System.currentTimeMillis();
        System.out.println(">>>>>>>>>>>>>>>:"+(l3-l2));

2.0结果
>>>>>>>>>>>:2434(查询50w)
>>>>>>>>>>>>>>>:32490(执行50w,比上次时间高出了4倍!)

 

描述:
方法一和方法二结果基本一致,这两个都是基本的更新某个或者某几个字段
方法三除了多了一次50w的循环, List<Pair<Query, Update>> updates=new ArrayList<>();里面会在mongo内部执行50w操作,所以耗时比较严重。

 

<<<<<<<<<<<<<<<<<<<<<<<<<<<<<华丽分割线>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

 

 

上述整体不变,改变个计划
  query0.fields().include("phone");
把所有字段都查询出来,比较耗时。
>>>>>>>>>>>:6634(查询处理慢了3倍不到)
>>>>>>>>>>>>>>>:7890(执行时间相对于方法一和方法二整体时间没差别)

 

posted @ 2023-08-26 14:17  余生请多指教ANT  阅读(2027)  评论(0编辑  收藏  举报