JSON格式:
{
"_id": "123456",
"total": 10,
"name": "测试1234",
"createTime": "2022-10-13 10:15:46",
"jsonBody": [
{
"children": [
{
"data": {
"name": "a"
},
"children": [
{
"data": {
"name": "b"
},
"children": [
{
"data": {
"name": "c",
"flag": "true"
},
"children": []
}
]
}
]
}
]
}
]
}
1.查询
分页求total 是大坑
数据量不大可以直接用 mongoTemplate.count()
数据量大,但是没有查询条件用 :
mongoTemplate.getCollection(“collectionName”).estimatedDocumentCount();
大量数据并且有查询条件,命中数据多 无解 建议用 原生查询,或者在功能上解决,只显示一万条等。
mongoTemplate.executeCommand()
分页排序(倒序)
query.skip((pageNum-1)*pageSize).limit(pageSize);
query.with(Sort.by("createTime").descending());
模糊查询(左匹配)
Query query = new Query();
query.addCriteria(Criteria.where("name").regex(Pattern.compile("^"+ name)+".*$"));
and和or查询
orOperator
Criteria criteria = Criteria.where("name").is("测试1234");
criteria.orOperator(criteria, Criteria.where("name").is("测试5678");
andOperator
Query query = new Query();
query.addCriteria(new Criteria().andOperator(
Criteria.where("name").is("测试1234"),
Criteria.where("name").is("测试5678")));
指定保留/排除字段
排除:
query.fields().exclude(name)
保留:
query.fields().include(name)
根据嵌套数据数据查询,返回的是一整条数据:
根据 c 查询
Query query = new Query();
query.addCriteria(Criteria.where("jsonBody")
.elemMatch(Criteria.where("children")
.elemMatch(Criteria.where("children")
.elemMatch(Criteria.where("children")
.elemMatch(Criteria.where("data.name").is("c");
字段自增自减
Update update = new Update();
自增:
update.inc("total");
自减:
update.inc("total",-1);
mongoTemplate.updateMulti(query,update,COLLECTION_NAME);
批量更新内嵌数组指定字段
修改内嵌数组中flag 为true 的name
public static final String JSONBODY_NAME_C = "jsonBody.$[].children.$[].children.$[].children.$[children].data.name";
Update update = new Update();
//更新过滤条件
update.filterArray(Criteria.where("child.data.flag").is("true");
update.set(JSONBODY_NAME_C , "ccc");
mongoTemplate.updateMulti(query, update, COLLECTION_NAME);
删除内嵌数组中的对象
删除内嵌数组中name为c 的对象,相当于根据key 删value
查询query 参考上面
String path = “jsonBody.$[].children.$[].children.$[].children”;
Query query1 = Query.query(Criteria.where("data.name").is(“c”);
Update update1 = new Update();
update1.pull(path, query1);
mongoTemplate.updateMulti(query, update1, COLLECTION_NAME);
根据JSON路径获取数据用 JSONPath
先获取 jsonObject
List<JSONObject> datas = (List<JSONObject>) JSONPath.eval(jsonObject,“$.jsonBody.children.data[*]”);
这里强转会报错,需要处理一下
ObjectMapper mapper=new ObjectMapper();
List<JSONObject> list = mapper.convertValue(datas, new TypeReference<List<JSONObject>>() { });
批量插入
BulkOperations operations = mongoTemplate.bulkOps(BulkOperations.BulkMode.ORDERED, COLLECTION_NAME);
operations.insert(这里是数据对象集合);
operations.execute();
管道查询,这个有很多资料
Aggregation aggregation = Aggregation.newAggregation(
Aggregation.match(criteria),
Aggregation.unwind(""),
Aggregation.project().andExclude(""),
Aggregation.sort(Sort.Direction.DESC, "createTime"),
Aggregation.skip((pageNum - 1) * pageSize),
Aggregation.limit(pageSize)
).withOptions(Aggregation.newAggregationOptions().allowDiskUse(true).build());
List<JsonObject> result = mongoTemplate.aggregate(aggregation, COLLECTION_NAME, JsonObject.class).getMappedResults();```
关于uwind:可以将数组拆分为单独的文档
例如jsonBody是个数组,只想操作数组下标为0可以按已下方法写
AggregationOperation unwindOperation = ctx -> new Document("$unwind",
new Document("path", "$jsonBody")
.append("includeArrayIndex", "arrayIndex")
);
//下面是聚合语句中的保留字段的写法,类似于query.fields().include();不会改变数据结构。
AggregationOperation projectOperation = ctx -> new Document("$project",
new Document("jsonBody.children.children.children.data.name", 1)
);
Aggregation aggregation = Aggregation.newAggregation(
Aggregation.match(Criteria.where("_id").is("123456")),
unwindOperation,
Aggregation.match(Criteria.where("arrayIndex").is(0)),
projectOperation
);
模糊查询字段并去重取前10数据
Fields fields = Fields.fields("name");
Aggregation aggregation = Aggregation.newAggregation(
Aggregation.project(fields).andExclude("_id"),
Aggregation.match(new Criteria("name").regex(".*" + message + ".*")),
Aggregation.group(fields).first("$$ROOT").as("result"),
Aggregation.limit(10),
Aggregation.replaceRoot("result")
);
mongoTemplate.aggregate(aggregation, COLLECTION_NAME_ENTITY, JSONObject.class)
.getMappedResults();