新开发的项目数据库是使用MongoDB,关于MongoDB的查询网上也有很多,在这里做一个学习、记录,后续会持续更新。
欢迎留言交流~
1. 多表联合查询
SQL实现
db.AA_Student.aggregate([
"$lookup":{
"from":"AA_Score", // 从表表名
"localField":"code", // 查询主表的关联字段
"foreignField":"studentCode", // 从表的关联字段,相对于AA_Score表的外键
"as":"score" // 联合查询出的别名,用于多条件查询表明前缀,相当于SQL中的临时表名
"$match":{ //条件筛选
"age":14,
"score.语文":{
"$gt":60
{ //分页
"$skip":0
"$limit":10
]).pretty()
查询结果
java实现
//'from'后面是副表名,‘localField’:主表关联字段,‘foreignField’:副表关联字段,
//‘as’:关联表的命名
LookupOperation lookupOperation = LookupOperation.newLookup().from("AA_Score").
localField("code").foreignField("studentCode").as("score1");
// 拼装具体查询信息
Criteria docCri = Criteria.where("score1").not().size(0);
docCri.and("age").is(14);
docCri.and("score1.语文").gte(60);
AggregationOperation match = Aggregation.match(docCri);
// 把条件封装成List
List<AggregationOperation> operations = new ArrayList<>();
operations.add(lookupOperation);
operations.add(match);
// 构建 Aggregation
Aggregation aggregation = Aggregation.newAggregation(operations);
// 执行查询
AggregationResults<Map> results = mongoTemplate.aggregate(aggregation, "AA_Student", Map.class);
List<Map> mapList = results.getMappedResults();
上面的关联查询只是两张表进行关联,如果想要一对多,就再创建一个LookupOperation对象,将对象添加到List集合中即可实现。因为MongoDB是非关系型数据库,所以项目中如果涉及数据量较大,应尽量避免使用关联查询!
2. 分页查询
Map<String, Object> resultMap = new HashMap<>();
int currentPage = 1;
int pageSize = 5;
//模糊查询
//Pattern pattern = Pattern.compile("^.*"+"s"+".*",Pattern.CASE_INSENSITIVE);
//Query query = Query.query(Criteria.where("provinceCode").regex(pattern));
Query query = new Query();
// 查询记录总数
int totalCount = (int) mongoTemplate.count(query, Map.class,"FAULT_MIN_DATA");
// 数据总页数
int totalPage = totalCount % pageSize == 0 ? totalCount / pageSize : totalCount / pageSize + 1;
// 设置记录总数和总页数
resultMap.put("totalCount", totalCount);
resultMap.put("totalPage", totalPage);
// 设置起始数
query.skip((currentPage - 1) * pageSize)
// 设置查询条数
.limit(pageSize);
// 排序
query.with(Sort.by(Sort.Direction.DESC,"cloud_create_time"));
// 查询当前页数据集合
List<Map> records = mongoTemplate.find(query, Map.class,"FAULT_MIN_DATA");
3. 聚合查询
List<AggregationOperation> operations = new ArrayList<>();
operations.add(Aggregation.group("turbineCode").count().as("TOTAL"));
Aggregation aggregation = Aggregation.newAggregation(operations);
AggregationResults<Map> map = mongoTemplate.aggregate(aggregation,"FAULT_MIN_DATA",Map.class);
List<Map> list = map.getMappedResults();
//正序排序
List mapList = (List) list.stream().sorted(Comparator.comparing(TestDemo::getCount)).collect(Collectors.toList());
mapList.forEach(map1 -> System.out.println(map1));
//倒序排序
Collections.sort(mapList, Comparator.comparing(TestDemo::getCount).reversed());
mapList.stream().limit(5).forEach(map1 -> System.out.println(map1));
4. $unwind用法
mongoDB中表的结构会存在多层嵌套,比如我项目中遇到的有五层嵌套之多。。。这种情况下,你在处理嵌套数据时,就用到
unwind
操作符了。
$unwind
:
将文档中的某一个数组类型字段拆分成多条,每条数据分别包含数组中的一个值。
原数据如下所示:
大家关注一下“_id”即可,这个表中数据嵌套四层,
mongo查询sql:
db.XXXX.aggregate([
{ "$unwind" : "$dataMinReses"},
{ "$unwind" : "$dataMinReses.dataMinStatuses"},
]).pretty()
java查询:
List<AggregationOperation> operations = new ArrayList<>();
operations.add(Aggregation.unwind("dataMinReses"));
operations.add(Aggregation.unwind("dataMinReses.dataMinStatuses"));
operations.add(Aggregation.match(criteria));
operations.add(Aggregation.sort(Sort.Direction.DESC,"faultSystemCode"));
Aggregation aggregation = Aggregation.newAggregation(operations);
AggregationResults<Map> aggregate = mongoTemplate.aggregate(aggregation, Constant.DATA_MIN_RESOURCE_TABLE_NAME, Map.class);
查询结果如下:
此时“dataMinStatuses”层的数据已经拆分出来,这时候对该层的数据进行过滤查询就能直接返回对应的数据了。
需要获取第几层的数据就要写几个$unwind
5.$push用法
介绍:
push添加指定的值到数组中,具体的可以参考官方文档:
https://docs.mongodb.com/manual/reference/operator/update/push/
这里我介绍的是与group配合使用,获取除分组字段外其他的字段信息;我这里是对字段"lpno"进行分组将字段"code",“name”,"alisasName"的信息放到一起,获取数据。
db.getCollection("TURBINE").aggregate([
"$group":{"_id":"$lpno",
"total":{
"$push":"$code"
"name":{
"$push":"$name"
"alineName":{
"$push":"$alisasName"
"$sort":{"_id":1}
]).pretty()
java中group与push配合使用:
List<AggregationOperation> operations = new ArrayList<>();
operations.add(Aggregation.group("lpno").push("name").as("name").push("alisasName").as("alisasName").count().as("TOTAL"));
--------------------------------------------------
2021.05.28 记录一下数据库多级目录的新增和修改
数据库中数据结构:
{
"_id":"56781afafa",
"tags":[
"_id":"1111",
"name":"涡轮"
"_id":"2222",
"name":"主控"
}
对tags里面的数据进行添加
"tagsList"是先查出数据库中存在的tags,再将新增数据add进去。
Query query = Query.query(Criteria.where("_id").is(id));
Update update = new Update();
update.set("tags",tagsList);
mongoTemplate.upsert(query,update,tableName);
对tags里面的数据进行修改,tags是修改的数据
Query query = Query.query(Criteria.where("_id").is(id).and(tags._id).is(childId));
Update update = new Update();
update.set("tags.$",tags);
mongoTemplate.updateFirst(query,update,tableName);
对tags里面的数据进行删除,
Query query = Query.query(Criteria.where(tags._id).is(childId));
Update update = new Update();
Document doc = new Document();
doc.put("_id",childId);
update.pull("tags",doc);
mongoTemplate.updateMulti(query,update,tableName);