ToB企服应用市场:ToB评测及商务社交产业平台

标题: MongoDB + SpringBoot 的基础CRUD、聚合查询 [打印本页]

作者: 傲渊山岳    时间: 2023-5-18 13:36
标题: MongoDB + SpringBoot 的基础CRUD、聚合查询
1、数据准备

1.1、springboot导包

点击查看代码
  1.         
  2.         <dependency>
  3.             <groupId>org.springframework.boot</groupId>
  4.             <artifactId>spring-boot-starter-data-mongodb</artifactId>
  5.         </dependency>
  6.         
  7.         <dependency>
  8.             <groupId>com.alibaba</groupId>
  9.             <artifactId>fastjson</artifactId>
  10.             <version>1.2.83</version>
  11.         </dependency>
复制代码
1.2、配置文件yml

点击查看代码
  1. spring:
  2.   data:
  3.     mongodb:
  4.       # 有账号密码
  5.       uri: mongodb://账户名:密码@IP:端口/数据库
  6.       # 无账号密码
  7.       # uri: mongodb://IP:端口/数据库
复制代码
1.3、实体类

点击查看代码
  1. package com.cc.mdb.entity;
  2. import lombok.Data;
  3. import org.springframework.data.annotation.Id;
  4. import org.springframework.data.mongodb.core.mapping.Document;
  5. import org.springframework.data.mongodb.core.mapping.Field;
  6. import java.time.LocalDateTime;
  7. /**
  8. * @Document("User") 存入的时候不取对象名,默认用User当做表名
  9. */
  10. @Data
  11. @Document("User")
  12. public class User {
  13.     @Id
  14.     private String id;
  15.     /**
  16.      * 使用name当做字段key
  17.      */
  18.     @Field("name")
  19.     private String name;
  20.     /**
  21.      * 使用age1当做字段key
  22.      */
  23.     @Field("age1")
  24.     private Integer age;
  25.     /**
  26.      * 使用email当做字段key
  27.      */
  28.     @Field("email")
  29.     private String email;
  30.     /**
  31.      * 使用createDate当做字段key
  32.      */
  33.     @Field("createDate")
  34.     private LocalDateTime createDate = LocalDateTime.now();
  35. }
复制代码
2、基础CRUD

点击查看代码
  1. package com.cc.mdb.test;
  2. import com.alibaba.fastjson.JSONObject;
  3. import com.cc.mdb.BaseTest;
  4. import com.cc.mdb.entity.User;
  5. import com.mongodb.client.result.UpdateResult;
  6. import org.junit.Test;
  7. import org.springframework.data.domain.PageRequest;
  8. import org.springframework.data.domain.Pageable;
  9. import org.springframework.data.domain.Sort;
  10. import org.springframework.data.mongodb.core.MongoTemplate;
  11. import org.springframework.data.mongodb.core.query.Criteria;
  12. import org.springframework.data.mongodb.core.query.Query;
  13. import org.springframework.data.mongodb.core.query.Update;
  14. import javax.annotation.Resource;
  15. import java.util.ArrayList;
  16. import java.util.Collection;
  17. import java.util.List;
  18. import java.util.regex.Pattern;
  19. /** CRUD
  20. *  查询使用:Query
  21. *  博客:https://blog.csdn.net/weixin_44185213/article/details/125293170?spm=1001.2014.3001.5502
  22. * @author CC
  23. * @since 2023/3/30 0030
  24. */
  25. @SpringBootTest
  26. @RunWith(SpringRunner.class)
  27. public class TestMongoQuery{
  28.     @Resource
  29.     private MongoTemplate mongoTemplate;
  30.     //写入简单数据 —— 根据对象存数据
  31.     @Test
  32.     public void test01()throws Exception{
  33.         List<User> vos = new ArrayList<>();
  34.         for (int i = 10; i < 20; i++) {
  35.             User user = new User();
  36.             String aa = i + "" + i + "" + i + "";
  37.             user.setId(aa);
  38.             user.setName("cscs"+aa);
  39.             user.setAge(123);
  40.             user.setEmail("11@qq.com");
  41.             vos.add(user);
  42.         }
  43.         Collection<User> user2 = mongoTemplate.insert(vos, "User2");
  44.         System.out.println(user2);
  45.     }
  46.     //写入简单数据 —— 根据json存数据(JSONObject(Fastjson))
  47.     @Test
  48.     public void test02()throws Exception{
  49.         List<JSONObject> vos = new ArrayList<>();
  50.         for (int i = 1; i < 20; i++) {
  51.             JSONObject result = new JSONObject();
  52.             String aa = i + "" + i + "" + i + "";
  53.             result.put("id",aa);
  54.             result.put("name","cscs"+aa);
  55.             result.put("age",123);
  56.             result.put("email","11@qq.com");
  57.             vos.add(result);
  58.         }
  59.         Collection<JSONObject> user3 = mongoTemplate.insert(vos, "User3");
  60.         System.out.println(user3);
  61.     }
  62.     //写入复杂数据 —— 有子文档(json数据中有下级)
  63.     @Test
  64.     public void test013()throws Exception{
  65.         List<JSONObject> vos = new ArrayList<>();
  66.         for (int i = 1; i < 20; i++) {
  67.             JSONObject result = new JSONObject();
  68.             String aa = i + "" + i + "" + i + "";
  69.             result.put("id",aa);
  70.             result.put("name","cscs"+aa);
  71.             result.put("age",123);
  72.             result.put("email","11@qq.com");
  73.             List<JSONObject> jss = new ArrayList<>();
  74.             for (int j = 0; j < 2; j++) {
  75.                 JSONObject js = new JSONObject();
  76.                 js.put("sId",j);
  77.                 js.put("sName","学校" + aa);
  78.                 js.put("sNo","学校编号" + aa);
  79.                 js.put("sTab",1);
  80.                 List<JSONObject> whats = new ArrayList<>();
  81.                 if (i == 1){
  82.                     for (int k = 0; k < 2; k++) {
  83.                         JSONObject kk = new JSONObject();
  84.                         kk.put("kId",k);
  85.                         kk.put("kName","k"+k);
  86.                         whats.add(kk);
  87.                     }
  88.                 }
  89.                 js.put("sWhat",whats);
  90.                 jss.add(js);
  91.             }
  92.             result.put("school",jss);
  93.             vos.add(result);
  94.         }
  95.         Collection<JSONObject> user3 = mongoTemplate.insert(vos, "User4");
  96.         System.out.println(user3);
  97.     }
  98.     //查找全部
  99.     @Test
  100.     public void test03()throws Exception{
  101.         List<User> users = mongoTemplate.findAll(User.class);
  102.         System.out.println(users);
  103.     }
  104.     /** 根据json里面的字段查询
  105.      * 查询 school.sWhat.kId 的数据
  106.      */
  107.     @Test
  108.     public void test07()throws Exception{
  109.         //查询的新增方法:test013
  110.         Criteria cr = new Criteria();
  111. //        cr.and("id").is("111");
  112. //        cr.and("school.sId").is(0);
  113.         cr.and("school.sWhat.kId").is(0);
  114.         Query query = new Query();
  115.         query.addCriteria(cr);
  116.         // 执行查询并获取结果
  117.         List<JSONObject> jsonObjects = mongoTemplate.find(query, JSONObject.class, "User4");
  118.         System.out.println(jsonObjects);
  119.     }
  120.     //**高级查询:使用Query
  121.     @Test
  122.     public void test04()throws Exception{
  123.         String search = "cscs";
  124.         int page = 1;
  125.         int size = 20;
  126.         Query query = new Query();
  127.         //一、where
  128.         //1模糊
  129.         String format = String.format("^.*%s.*$", search);
  130.         Pattern pattern = Pattern.compile(format, Pattern.CASE_INSENSITIVE);
  131.         Criteria criteria = Criteria.where("name").regex(pattern);
  132.         //模糊查询方式2(推荐)
  133. //        Criteria.where("name").regex(String.format(".*%s.*","查询的值"));
  134.         //2等于(这里比较特殊,value:数字的必须传入数字的、字符串必须传入字符串的)
  135.         criteria.and("age").is(123);
  136.         query.addCriteria(criteria);
  137.         //二、排序。按id升序
  138.         Sort sort = Sort.by(Sort.Direction.ASC, "_id");
  139.         query.with(sort);
  140.         //二、总条数(是所有条件都弄了之后)
  141.         long totalCount = mongoTemplate.count(query, JSONObject.class, "User3");
  142.         //三、分页(必须在where和查询总条数之后)
  143.         //方式1
  144. //        query.skip((page - 1) * size).limit(size);
  145.         //方式2(推荐)
  146.         Pageable pageable = PageRequest.of(page - 1, size);
  147.         query.with(pageable);
  148.         //查询。由于查询出来的是key-value的形式,可以使用JSONObject(FastJson)来接收参数。如果有对象(User),可以直接使用对象来接收
  149.         List<JSONObject> users = mongoTemplate.find(query, JSONObject.class, "User3");
  150.         System.out.println("总条数:" + totalCount);
  151.         System.out.println(users);
  152.     }
  153.     //修改 - 根据表名+id 修改其中一个json中的某些值
  154.     @Test
  155.     public void test05() {
  156.         JSONObject user2 = mongoTemplate.findById("6433c76df108474b788cc4ce", JSONObject.class, "User3");
  157.         Object id = user2.get("_id");
  158.         Query query = new Query(Criteria.where("_id").is(id));
  159.         Update update = new Update();
  160.         update.set("name", "修改后的名字2");
  161.         update.set("age", "321");
  162. //        update.set("email", "");
  163.         //方式1:upsert方法更新与查询条件匹配的第一个文档,如果没有文档与查询条件匹配,则插入一个新文档。
  164. //        UpdateResult result = mongoTemplate.upsert(query, update, "User3");
  165. //        long count = result.getModifiedCount();
  166. //        System.out.println(count);
  167.         //方式2:update方法更新与查询条件匹配的第一个文档
  168.         UpdateResult user3 = mongoTemplate.updateFirst(query, update, "User3");
  169.         //修改计数
  170.         long modifiedCount = user3.getModifiedCount();
  171.         System.out.println(modifiedCount);
  172.         //匹配计数
  173.         long matchedCount = user3.getMatchedCount();
  174.         System.out.println(matchedCount);
  175.         //方式3:updateMulti方法更新与查询条件匹配的所有文档。
  176. //        UpdateResult user31 = mongoTemplate.updateMulti(query, update, "User3");
  177.     }
  178.     //删除 - 根据数据id删除
  179.     @Test
  180.     public void test06() {
  181.         //1删除文档中的某一条数据
  182. //        Query query = new Query(Criteria.where("_id").is("6433c76df108474b788cc4cf"));
  183. //        DeleteResult result = mongoTemplate.remove(query, "User3");
  184. //        long count = result.getDeletedCount();
  185. //        System.out.println(count);
  186.         //2删除整个文档中的数据 —— 相当于drop清空表中的数据
  187. //        DeleteResult user4 = mongoTemplate.remove(new Query(), "User4");
  188. //        long deletedCount = user4.getDeletedCount();
  189. //        System.out.println(deletedCount);
  190.         //3删除文档 —— 相当于删除表
  191.         mongoTemplate.dropCollection("User4");
  192.     }
  193. }
复制代码
3、聚合查询

3.1、聚合查询关键字
  1. *      $project            指定返回字段
  2. *      $lookup                    多表关联
  3. *      $unwind                    数组拆分
  4. *      $match                    筛选条件
  5. *      $sort                    排序
  6. *      $limit                    分页
  7. *      $skip                    跳过
  8. *      $group                    根据id(可自定义)分组
  9. *      $sum                    分组后求和
  10. *      $first                    分组后取第一条
  11. *      $last                    分组后取最后一条
  12. *      $addToSet           分组后添加到list
  13. *      $cond                    可以做 if-else
复制代码
3.2、聚合查询

点击查看代码
  1. package com.cc.mdb.test;
  2. import com.alibaba.fastjson.JSONObject;
  3. import com.cc.mdb.BaseTest;
  4. import org.junit.Test;
  5. import org.springframework.data.domain.Sort;
  6. import org.springframework.data.mongodb.core.MongoTemplate;
  7. import org.springframework.data.mongodb.core.aggregation.*;
  8. import org.springframework.data.mongodb.core.query.Criteria;
  9. import javax.annotation.Resource;
  10. import java.util.ArrayList;
  11. import java.util.Collection;
  12. import java.util.List;
  13. /**
  14. * 聚合查询
  15. *      $project                指定返回字段
  16. *      $lookup                    多表关联
  17. *      $unwind                    数组拆分
  18. *      $match                    筛选条件
  19. *      $sort                    排序
  20. *      $limit                    分页
  21. *      $skip                    跳过
  22. *      $group                    根据id(可自定义)分组
  23. *      $sum                    分组后求和
  24. *      $first                    分组后取第一条
  25. *      $last                    分组后取最后一条
  26. *      $addToSet                分组后添加到list
  27. *      $cond                    可以做 if-else
  28. * @author CC
  29. * @since 2023/4/20 0020
  30. */
  31. public class TestMongoAgg extends BaseTest {
  32.     @Resource
  33.     private MongoTemplate mongoTemplate;
  34.     private static final String COLLECTION_NAME = "USER";
  35.     /** 分组
  36.      */
  37.     @Test
  38.     public void test00()throws Exception{
  39.         Aggregation groupAgg = Aggregation.newAggregation(
  40.                 Aggregation.group("age") // 分组条件
  41.                         .first("age").as("age_R")     // 获取分组后查询到的该字段的第一个值
  42. //                        .first("school.sId").as("sId_R")
  43.                         .sum("age").as("sum_age_R")  // 按分组对该字段求和
  44.                         .avg("age").as("avg_age_R")  // 按分组求该字段平均值
  45.                         .sum("id").as("sum_id_R")    // 按age分组后求id的和
  46.                         .min("id").as("min_id_R")    // 按age分组后求id的最小值
  47.                         .max("id").as("max_id_R")    // 按age分组后求id的最大值
  48.         );
  49.         AggregationResults<JSONObject> results = mongoTemplate.aggregate(groupAgg, COLLECTION_NAME, JSONObject.class);
  50.         List<JSONObject> res = results.getMappedResults();
  51.         System.out.println(res);
  52.     }
  53.     /** 聚合查询:数组拆分 + 指定返回字段 + 排序 + 分页
  54.      */
  55.     @Test
  56.     public void testAgg01()throws Exception{
  57.         // 1. 配置聚合查询
  58.         // 1.1. 将school字段分解成数组
  59.         UnwindOperation unwind = Aggregation.unwind("school");
  60.         // 1.2. 获取school.sId的属性中大于2的对象
  61.         MatchOperation match = Aggregation.match(Criteria.where("school.sId").gt(2));
  62.         // 1.3. 显示的字段
  63.         ProjectionOperation project = Aggregation.project("_id", "school.sId",
  64.                 "school.sName", "name", "id", "age", "email");
  65.         // 1.4. 查询所有
  66.         Aggregation aggregation = Aggregation.newAggregation(
  67.                 unwind,
  68.                 match,
  69.                 project
  70.         );
  71.         // 1.5. 查询数量:把数量封装在totalCount这个值中
  72.         Aggregation countAgg = Aggregation.newAggregation(
  73.                 unwind,
  74.                 match,
  75.                 Aggregation.count().as("totalCount")
  76.         );
  77.         // 1.6. 排序+分页
  78.         Aggregation sortAndSkipLimitAgg = Aggregation.newAggregation(
  79.                 unwind,
  80.                 match,
  81.                 project,
  82.                 // 1.6.1. 排序:先按照sId升序,再按照id降序
  83.                 Aggregation.sort(Sort.Direction.ASC,"sId")
  84.                         .and(Sort.Direction.DESC,"id"),
  85.                 // 1.6.2. 分页
  86.                 Aggregation.skip(0L),
  87.                 Aggregation.limit(2L)
  88.         );
  89.         // 2. 查询
  90.         // 2.1. 查询全部
  91.         AggregationResults<JSONObject> results = mongoTemplate.aggregate(aggregation, COLLECTION_NAME, JSONObject.class);
  92.         // 2.1.1. 获取映射结果
  93.         List<JSONObject> allResult = results.getMappedResults();
  94.         allResult.forEach(System.out::println);
  95.         // 2.2. 查询数量
  96.         AggregationResults<JSONObject> resultCount = mongoTemplate.aggregate(countAgg, COLLECTION_NAME, JSONObject.class);
  97.         JSONObject jsonObject = resultCount.getUniqueMappedResult();
  98.         System.out.println(jsonObject);
  99.         Object totalCount = jsonObject.get("totalCount");
  100.         System.out.println("总数:" + totalCount);
  101.         // 2.3. 排序+分页查询
  102.         AggregationResults<JSONObject> sortSkip = mongoTemplate.aggregate(sortAndSkipLimitAgg, COLLECTION_NAME, JSONObject.class);
  103.         List<JSONObject> mappedResults = sortSkip.getMappedResults();
  104.         System.out.println(mappedResults);
  105.         //获取原始结果
  106. //        Document rawResults = results.getRawResults();
  107.         //获取唯一映射结果(只获取一个值)
  108. //        JSONObject uniqueMappedResult = results.getUniqueMappedResult();
  109.         //获取服务器使用情况
  110. //        String serverUsed = results.getServerUsed();
  111.         //循环:和mappedResults循环一样的
  112. //        results.forEach(result -> {
  113. //            System.out.println(result);
  114. //        });
  115.     }
  116.     //添加聚合查询的数据
  117.     @Test
  118.     public void testAgg02() throws Exception {
  119.         //写入复杂数据 —— 有子文档(json数据中有下级)
  120.         List<JSONObject> vos = new ArrayList<>();
  121.         for (int i = 1; i < 20; i++) {
  122.             JSONObject result = new JSONObject();
  123.             String aa = i + "" + i + "" + i + "";
  124.             result.put("id", aa);
  125.             result.put("name", "cscs" + aa);
  126.             int age = 123;
  127.             if (i >= 10){
  128.                 age = 345;
  129.             }
  130.             result.put("age", age);
  131.             result.put("email", "11@qq.com");
  132.             List<JSONObject> jss = new ArrayList<>();
  133.             if (i < 6){
  134.                 for (int j = 1; j < 3; j++) {
  135.                     JSONObject js = new JSONObject();
  136.                     js.put("sId", j * i);
  137.                     js.put("sName", "学校" + aa);
  138.                     js.put("sNo", "学校编号" + aa);
  139.                     js.put("sTab", j * i);
  140.                     jss.add(js);
  141.                 }
  142.             }
  143.             result.put("school", jss);
  144.             vos.add(result);
  145.         }
  146.         Collection<JSONObject> user3 = mongoTemplate.insert(vos, COLLECTION_NAME);
  147.         System.out.println(user3);
  148.     }
  149. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4