MongoDB升级-从3.2到4.0心路历程

前言

本次升级是2019年12月底完成. 升级过程中发现百度到的内容十分有限,
大部分时候都是翻看官方文档. 因此考虑写一篇文章帮助后来者.
本文仅供需要尝鲜的用户/企业做一个参考. 如有错误, 请指正.
本文为原创文章, 转载请注明出处.

升级工作

  • MongoDB Driver版本: 查询mongo的官方文档, 发现需要升级到3.8.0以上, 具体驱动支持情况如下图
    在这里插入图片描述
<dependency>
	<groupId>org.mongodb</groupId>
	<artifactId>mongo-java-driver</artifactId>
	<version>3.12.0</version>
</dependency>
  • 如果没有用原生mongodb-java-driver, 而是用的spring-data-mongodb进行操作的话, 则无需单独引入driver, 只需要引入新版本spring-data-mongodb即可.
    注意: spring-data-mongodb是从2.2.3开始支持MongoDB4.0的, spring-data-mongodb 2.2.3是2019.12.04发布(我升级时当月月初…)
<dependency>
	<groupId>org.springframework.data</groupId>
	<artifactId>spring-data-mongodb</artifactId>
	<version>2.2.3.RELEASE</version>
</dependency>
  • 使用了spring-data-mongodb的情况下, 需要升级所有依赖spring framework的版本到5.2.2, 如:
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-beans</artifactId>
	<version>5.2.2.RELEASE</version>
</dependency>
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-context</artifactId>
	<version>5.2.2.RELEASE</version>
</dependency>
<!-- ...此处省略其他组件, 有多少spring组件就升级多少个, 都升到5.2.2版本 -->
  • 升级spring framework之后, 官网文档中提到, 需要依赖jackson版本2.10.x
<dependency>
	<groupId>com.fasterxml.jackson.core</groupId>
	<artifactId>jackson-annotations</artifactId>
	<version>2.10.1</version>
</dependency>
<dependency>
	<groupId>com.fasterxml.jackson.core</groupId>
	<artifactId>jackson-core</artifactId>
	<version>2.10.1</version>
</dependency>
<dependency>
	<groupId>com.fasterxml.jackson.core</groupId>
	<artifactId>jackson-databind</artifactId>
	<version>2.10.1</version>
</dependency>
<dependency>
	<groupId>com.fasterxml.jackson.jaxrs</groupId>
	<artifactId>jackson-jaxrs-json-provider</artifactId>
	<version>2.10.1</version>
</dependency>

启动项目发现全局编译报错, 原因是:

spring-data 提供的 mongoTemplate 的很多方法 (API) 变了, 没有做过时处理, 而是直接硬性的移除/变更了.

这就很要命了, 于是又去查看官方文档, 根据官方文档的说辞, 把报错的地方进行修改. 下面举例子

关于更新操作的返回值API

// 旧代码 WriteResult 已经没有了。
WriteResult wr = this.mongoTemplate().updateMulti();
int n = writeResult.getN();
// 新版的api updateResult 提供了
UpdateResult result = this.mongoTemplate.updateMulti(query, update, "xxx_connection");
result.getModifiedCount(); // 更改的数量
result.getMatchedCount(); // 匹配的数量

排序:

第一种方法:

Query query = new Query();
query.with(Sort.by(new Sort.Order(Sort.Direction.DESC, form.getSort())));

第二种方法:推荐。

Query query= new Query();
query.with(Sort.by(form.getSort()).descending()); // 倒序
query.with(Sort.by(form.getSort()).ascending()); // 正序

第三种方法: 函数式编程

	// 针对name属性进行升序
Query query= new Query();
query.with(Sort.sort(XxxEntity.class).by(XxxEntity:: getName).ascending()); 

简单查询:

一. 游标方式查询:

  • 旧语法:
DBCursor = mongoTemplate.getCollection("xxx_connection_name")find(query.getQueryObject());
dbCursor.addOption(16);
while (dbCursor.hasNext()) {
	Map repaymentInfo= dbCursor.next().toMap();
	map = new HashMap<>();
	map.put("身份证号",GetterUtil.getString(repaymentInfo.get("idNo")));
	// ...
}
dbCursor.close();
  • 新语法:

经测试,以下第一种也是可以迅速返回,不会产生大数据量时候的阻塞情况,同时Query对象有对cursor超时时间进行设置的api => noCursorTimeout()

第一种
CloseableIterator<HashMap> iterator = mongoTemplate.stream(query,
		HashMap.class, "xxx_connection_name");
while(iterator.hasNext()){
	// ...
}
第二种
FindIterable<Document> documents =
		mongoTemplate.getCollection("lxcs_spdb_interface_sendorder_job").find();
documents.noCursorTimeout(false);
while(documents.iterator().hasNext()){
	// ...
}
第三种

这种方案适用于 原代码中 对于游标循环出以后toMap的写法,改动较小

// 旧版代码
DBCursor dbCursor = mongoTemplate.getCollection("xxx_connection_name").find(query.getQueryObject());
while (dbCursor.hasNext()) {
	Map map = dbCursor.next().toMap();
}
// --------------------------------------------------
// 新版代码 document本身是implements了Map
MongoCursor<Document> cursor = mongoTemplate.getCollection("xxx_connection_name").find().cursor();
while (cursor.hasNext()) {
	Map map = cursor.next();
}
cursor.close();

二. 管道方式查询:

  • 旧语法:
DBObject group = (DBObject) JSON.parse("{}");
AggregationOperation aggregationOperationGroup = new AggregationOperation() {
	@Override
	public DBObject toDBObject(AggregationOperationContext context) {
		return group;
	}
};
// ...
  • 新语法:
Document group = Document.parse("{}");
AggregationOperation aggregationOperationGroup = new AggregationOperation() {
	@Override
	public Document toDocument(AggregationOperationContext context) {
		return group;
	}
};
// ...

此时, 单纯的mongodb就搞定了.


但是 为什么我说的是单纯的mongodb, 因为… 我们项目中还用到了elasticsearch, 版本是2.4.6, 并且整合了spring-data-elasticsearch

升级了spring-data-mongodb, 那么很明显的问题就是, 对应支持es的spring-data也需要升级, 否则其依赖的spring-data-common包会报错找不到某些方法/枚举之类的问题.

下一篇文章我再详细讲解elasticsearch的升级.

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值