spring data mongodb 批量操作(bulk)通过document更新整个文档报错 Invalid BSON field name xxx

因为bulk.upsert()和mongoTemplate.upsert()的内部对document这种全文档更新的实现不一样,所以导致批量执行报错,下面说明。

以下代码执行没有问题,正常更新
Document document = new Document();
mongoTemplate.getConverter().write(xxxPO, document);
Update update = Update.fromDocument(document);
mongoTemplate.upsert(Query.query(Criteria.where("_id").is(xxxPO.getId())),
                update, MongoConst.COLLECTION_NAME);

 

但是同样的操作放到bulk里就会失败,但是如果不用document转换这种方式,直接用update.set是没有问题的,所以问题就出在update上面,

BulkOperations bulk = mongoTemplate.bulkOps(BulkOperations.BulkMode.UNORDERED, xxxPO.class);
List<Pair<Query, Update>> updates = udps.stream().map(p -> {
                Document document = new Document();
                mongoTemplate.getConverter().write(p, document);
                Update update = Update.fromDocument(document);
                Query query = Query.query(Criteria.where("_id").is(p.getId()));
                Pair<Query, Update> pair = Pair.of(query, update);
                return pair;
            }).collect(Collectors.toList());
bulk.upsert(updates);

 执行报错

java.lang.IllegalArgumentException: Invalid BSON field name xxx

打印document转换完的update对象:

{
    "isolated":false,
    "arrayFilters":[

    ],
    "updateObject":{
        "scenicSpotProductId":"4915367",
        "scenicSpotRuleId":"4915368",
        "ticketKind":"2",
        "startDate":"2021-12-31",
        "endDate":"2021-12-31",
        "weekDay":"1,2,3,4,5,6,7",
        "stock":99,
        "sellPrice":74,
        "settlementPrice":74,
        "replaceRule":0,
        "merchantCode":"320044720",
        "createTime":1637050139710,
        "updateTime":1637052559680,
        "floatPriceManually":false,
        "floatPriceType":1
    }
}

打印Update.set(key, value)方法返回的update对象

{
    "isolated":false,
    "arrayFilters":[

    ],
    "updateObject":{
        "$set":{
            "scenicSpotProductId":"4915367",
            "sellPrice":74,
            "settlementPrice":74,
            "updateTime":1637053306267
        }
    }
}

 发现document转换过的少了一层“$set”节点,但是update对象不支持直接改updateObject,所以在源对象上做文章,外面包一层map再转就可以了;

List<Pair<Query, Update>> updates = udps.stream().map(p -> {
                Document document = new Document();
                Map<String, xxxPO> s = Maps.newHashMap();
                s.put("$set", p);
                mongoTemplate.getConverter().write(s, document);
                Update update = Update.fromDocument(document);
                Query query = Query.query(Criteria.where("_id").is(p.getId()));
                Pair<Query, Update> pair = Pair.of(query, update);
                return pair;
            }).collect(Collectors.toList());
bulk.upsert(updates);

 第一段代码没问题是因为mongoTemplate下面的更新方法内部做了转换处理;

 bulk的所有更新方法都有这个问题,初步测试是没什么问题,只是文档里的_class会变成

java.util.HashMap,目前对业务没有影响,后续再观察。

以下是mongo版本和springdata版本,其它版本未测试。

mongodb 3.4.6
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-mongodb</artifactId>
                <version>2.3.1.RELEASE</version>
            </dependency>

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值