本文记录Spring Data Mongodb中对mongoDB查询及更新的实现.
使用场景
mongoDB中文档会具有较深的深度,在通过mongoTemplate进行处理时,需要注意使用的语法.本文介绍两种场景:深层次查询及更新
技术点
- mongoDB语法
- mongoTemplate接口API
mongoDB文档展示
{
"_id" : ObjectId("5d5684ae1599021e848d6736"),
"vehicleId" : "AP_4028b2b64fb20697014fdf7f65e44346",
"list" : [
{
"groupName" : "发动机系统",
"groupCode" : "1000",
"programs" : {
"vehicleId" : "AP_4028b2b64fb20697014fdf7f65e44346",
"groupCode" : "1000",
"list" : [
{
"baseItemName" : "清洗喷油嘴",
"baseItemCode" : "QX040001",
"itemDesc" : "20000km或24个月/次",
"judge" : "1"
},
{
"baseItemName" : "润滑系统清洁养护",
"baseItemCode" : "QX010001",
"itemDesc" : "5000km/次",
"judge" : "0"
},
{
"baseItemName" : "清洗节气门",
"baseItemCode" : "QX020001",
"itemDesc" : "20000km或24个月/次",
"judge" : "0"
},
{
"baseItemName" : "清洗进气系统",
"baseItemCode" : "QX010002",
"itemDesc" : "20000km/次",
"judge" : "0"
},
{
"baseItemName" : "火花塞",
"baseItemCode" : "BY036055",
"judge" : "0"
}
]
}
},
{
"groupName" : "常规保养",
"groupCode" : "6000"
}
],
"_class" : "MaintenanceClassificationRespResult"
}
实现代码:深层次查询
深层次查询(方式一):
// 通过构造函数andOperator()连接and条件,通过elemMatch()指定子级节点
Query query = Query.query(new Criteria().andOperator(Criteria.where("vehicleId").is(vehicleId), Criteria.where("list").elemMatch(Criteria.where("groupCode").is(groupCode))));
// findOne()仅返回匹配的第一个文档,此处需注意返回的为整个文档,若需要指定返回内容,需要使用原生API,findOne()第三个入参为文档表名
MaintenanceClassificationRespResult result = mongoTemplate.findOne(query, MaintenanceClassificationRespResult.class, IEasyepcCode.EASYEPC_MONGODB_325021_325031);
深层次查询(方式二):
// 通过.的形式指定子级节点
Query query = new Query(Criteria.where("vehicleId").is(vehicleId).and("list.groupCode").is(groupCode));
深层次查询(方式三):
此处可以参考博文:学习MongoDB四:MongoDB查询
补充在mongoDB中通过正则表达式实现like查询的方式
Query query = new Query(Criteria.where("licenseNo").regex("^.*" + licenseNo + ".*$").and("storeId").is(storeId));
List<QueryEnquiryListResp.QueryEnquiryListForm> result = mongoTemplate.find(query, QueryEnquiryListResp.QueryEnquiryListForm.class, IUnderwriteCode.UNDERWRITE_MONGODB_ENQUIRY);
实现代码:深层次更新
深层次更新:
@Transactional(rollbackFor = Exception.class)
public void updateJudgeForMaintenanceClassificationList(String vehicleId, String groupCode, String baseItemCode) {
/*
* 由于MongoDB不支持多层占位更新,且占位符必须位于第一个位置,所以需要通过代码逻辑确认除第一层外的数组下标
* 需要先查询原两层结构
*/
MaintenanceClassificationRespResult tempResult = queryMaintenanceClassificationByMongoDB(MaintenanceClassificationReqModel
.builder().vehicleId(vehicleId).build());
if (!Objects.isNull(tempResult)) {
List<MaintenanceClassificationRespList> list = tempResult.getList();
for (int i = 0; i < list.size(); i++) {
MaintenanceClassificationRespList data = list.get(i);
if (groupCode.equals(data.getGroupCode())) {
// 保养项目分类一致,更新其下保养项目明细
if (!Objects.isNull(data.getPrograms()) && data.getPrograms().getList().size() > 0) {
for (int j = 0; i < data.getPrograms().getList().size(); j++) {
MaintenanceProgramRespList dataDetail = data.getPrograms().getList().get(j);
if (baseItemCode.equals(dataDetail.getBaseItemCode())) {
// 确认二层数据下标
Query query = Query.query(Criteria.where("vehicleId").is(vehicleId).and("list.programs.list.baseItemCode").is(baseItemCode));
Update update = new Update();
// 此处i可以替换为$
update.set("list." + i + ".programs.list." + j + ".judge", IEasyepcCode.JUDGE_1);
UpdateResult updateResult = mongoTemplate.updateFirst(query, update, IEasyepcCode.EASYEPC_MONGODB_325021_325031);
log.info("mongoDB更新文档结果:{}", updateResult.toString());
break;
}
}
}
break;
}
}
}
}
深层次更新:
@Transactional(rollbackFor = Exception.class)
public void updateJudgeForStructuralQueryList(String vehicleId, String partGroupId) {
// 存入mongoDB的数据id会自动转换为_id,使用实体接收没有问题,但是查询或更新时,需要使用_id
Query query = Query.query(new Criteria().andOperator(Criteria.where("vehicleId").is(vehicleId), Criteria.where("partGroupList").elemMatch(Criteria.where("_id").is(partGroupId))));
Update update = new Update();
update.set("partGroupList.$.judge", IEasyepcCode.JUDGE_1);
UpdateResult updateResult = mongoTemplate.updateFirst(query, update, IEasyepcCode.EASYEPC_MONGODB_221001);
log.info("mongoDB更新文档结果:{}", updateResult.toString());
}
备注
Spring Data Mongodb默认不开启事务,若果需要开启,可以参考Spring Data Mongodb事务管理