• MongoDB入门与实战-第四章-SpringBoot集成MongoDB


    参考

    SpringBoot 整合 MongoDB 实战解说

    MongoDB 连接

    Java 连接 MongoDB 服务器,与我们常用的连接关系型数据库方式类似!

    标准 URI 连接语法:

    mongodb://username:password@host1:port1,host2:port2,...,hostN:portN/database?options
    
    • 1

    参数说明:

    • mongodb://:这是固定的格式,必须要指定
    • username:password@:可选项,如果设置,在连接数据库服务器之后,驱动都会尝试登录这个数据库
    • host1:port1:主机IP和端口号,必须指定至少一个host。如果要连接复制集,请指定多个主机地址
    • /database:如果指定了username:password@,连接时会验证并登录指定数据库。若不指定,默认打开 test 数据库
    • ?options:连接可选项,例如connectTimeoutMS=5000ms,表示连接等待时间最长 5 秒

    例如,无密码连接 MongoDB

    mongodb://127.0.0.1:27017
    
    • 1

    使用用户名test,密码test登录 MongoDB 的test_db数据库

    mongodb://test:test@127.0.0.1:27017/test_db
    
    • 1

    无密码连接指定三台服务器 (端口 27017, 27018, 和27019)

    mongodb://127.0.0.1:27017,127.0.0.1:27018,127.0.0.1:27019
    
    • 1

    java客户端方式

    在这里插入图片描述

    引入驱动依赖

    参考:https://docs.mongodb.com/drivers/java/

    <dependency>
        <groupId>org.mongodbgroupId>
        <artifactId>mongo-java-driverartifactId>
        <version>3.12.7version>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    测试创建客户端

    public class MongoDBTest {
        private static final String MONGO_URL = "localhost";
        private MongoClient mongoClient = null;
    
        @Test
        public void testDb(){
            // 连接到数据库
            MongoDatabase mongoDatabase = mongoClient.getDatabase("test_iot");
            System.out.println("Connect to database successfully");
            mongoDatabase.createCollection("tower_crane_property");
            System.out.println("集合创建成功");
        }
    
        @BeforeEach
        public void initClient(){
            //连接到MongoDB服务,如果不指定库名,则需要admin的账号密码 如果是远程连接可以替换“localhost”为服务器所在IP地址
            mongoClient = MongoClients.create("mongodb://admin:123456@192.168.0.44:27017");
            // 指定库
            mongoClient = MongoClients.create("mongodb://admin:123456@192.168.0.44:27017/iot");
            // 增加库在哪里认证,在哪里创建
            mongoClient = MongoClients.create("mongodb://admin:123456@192.168.0.44:27017/iot?authSrouce=admin");
            
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    创建集合

    可以通过ValidationOptions增加字段校验,也可以指定集合大小
    在这里插入图片描述

    查询文档

    /**
         * 查询文档
         */
        @Test
        public void testQuery() {
            // 连接到数据库
            MongoDatabase mongoDatabase = mongoClient.getDatabase("iot");
            System.out.println("Connect to database successfully");
            //获取集合
            MongoCollection<org.bson.Document> collection = mongoDatabase.getCollection("device");
    
            //遍历所有文档
            FindIterable<org.bson.Document> findIterable = collection.find();
            MongoCursor<org.bson.Document> mongoCursor = findIterable.iterator();
            while(mongoCursor.hasNext()){
                System.out.println(mongoCursor.next());
            }
    
            //查询当前集合所有文档数量
            long count = collection.countDocuments();
            System.out.println("当前文档数量:" + count);
    
            //带条件遍历文档
            FindIterable<Document> documentFindIterable = collection.find(Filters.eq("code", "manager"));
            MongoCursor<Document> documentMongoCursor = documentFindIterable.iterator();
            while(documentMongoCursor.hasNext()){
                System.out.println(documentMongoCursor.next());
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    查询集合大小

    //查询当前集合所有文档数量
    long count = collection.countDocuments();
    
    • 1
    • 2

    条件查询

    在这里插入图片描述

    排序

    在这里插入图片描述

    投影

    在这里插入图片描述

    聚合查询

    对stars分组并计数
    在这里插入图片描述

    复合聚合

    excludeId不显示id,只显示firstCategory字段,这个字段是显示categories索引小标0的值,也就是categories中第一个值
    在这里插入图片描述
    效果
    在这里插入图片描述

    插入文档

    /**
         * 测试插入
         */
        @Test
        public void testInsert(){
            // 连接到数据库
            MongoDatabase mongoDatabase = mongoClient.getDatabase("iot");
            //获取集合
            MongoCollection<Document> collection = mongoDatabase.getCollection("device");
    
            //向集合中插入文档
            Document document = new Document("name", "管理员").
                    append("code", "manager").
                    append("sort", 100).
                    append("lat", 22.81503471517295).
                    append("lng", 108.37301005337522);
            List<Document> documents = new ArrayList<>();
            documents.add(document);
            collection.insertMany(documents);
            System.out.println("文档插入成功");
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    批量插入

    在这里插入图片描述

    更新文档

    在这里插入图片描述

    删除文档

    在这里插入图片描述

    SpringDataMongoDB

    添加依赖

    
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-data-mongodbartifactId>
            dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    配置文件

    server:
      port: 8083
    
    spring:
      data:
        mongodb:
          # 服务器地址
          host: 192.168.0.44
          # 端口
          port: 27107
          # 用户名
          username: iot_admin
          # 密码
          password: iot_admin
          # 认证数据库
          authentication-database: iot
          # 操作数据库
          database: iot
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    新建实体映射

    在这里插入图片描述

    插入文档

    在这里插入图片描述

    修改文档

    在这里插入图片描述

    /**
         * 更新对象
         * @param user
         */
        @Override
        public void updateUser(UserEntity user) {
            Query query=new Query(Criteria.where("id").is(user.getId()));
            Update update= new Update().set("userName", user.getUserName()).set("passWord", user.getPassWord());
            //更新查询返回结果集的第一条
            mongoTemplate.updateFirst(query,update,UserEntity.class);
            //更新查询返回结果集的所有
            // mongoTemplate.updateMulti(query,update,UserEntity.class);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    删除

    /**
         * 删除对象
         * @param id
         */
        @Override
        public void deleteUserById(Long id) {
            Query query=new Query(Criteria.where("id").is(id));
            mongoTemplate.remove(query,UserEntity.class);
        }
    /***********方法二************/
    /**
         * 删除
         *
         * @param id id
         * @return ApiResponse
         */
        public ApiResponse delete(String id) {
            try {
                Query query = new Query(Criteria.where("_id").is(id));
                DeleteResult result = mongoTemplate.remove(query, Student.class);
                long count = result.getDeletedCount();
                if (count > 0) {
                    return Api.ok(count, "删除成功");
                }
                throw new ServiceException(-1, String.format("【%s】%s", id, "不存在"));
            } catch (ServiceException e) {
                throw e;
            } catch (Exception e) {
                throw new SystemException(-1, "删除出错");
            }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    高级查询

    查询某一天的数据

    public PageDTO<ElevatorAlarmDTO> findTodayList(DevicePageQueryDTO param) {
            /*
            相差8个时区
            24 = 16 + 8
            db.getCollection("elevator_alarm").find({deviceCode:"1589581864182480897",timestamp:{"$gte":ISODate("2022-11-07T16:00:00.000Z")}}).sort({timestamp:-1})
    
             */
    //        todayStr = todayStr + "T16:00:00.000Z";
            PageDTO<ElevatorAlarmDTO> result = new PageDTO<>();
            int pageIndex = param.getPageIndex();
            int pageSize = param.getPageSize();
            result.setPageSize(pageSize);
            //mongodb查询条件
            Query query = new Query();
            query.addCriteria(Criteria.where(IotConstant.FIELD_DEVICE_CODE).is(param.getDeviceCode()));
    
            String todayStr = DateUtil.date().toDateStr();
            Date today = DateUtil.parseDateTime(todayStr+" 00:00:00");
            query.addCriteria(Criteria.where(IotConstant.FIELD_TIME).gte(today));
            // 如下两种写法不可以
    //        query.addCriteria(Criteria.where(IotConstant.FIELD_TIMESTAMP).gte("ISODate(\""+todayStr+"\")"));
    //        query.addCriteria(Criteria.where(IotConstant.FIELD_TIMESTAMP).gte("ISODate(2022-11-07T16:00:00.000Z)"));
            long count = mongoTemplate.count(query,getClazz());
            result.setTotalCount(count);
            if (count > 0){
                long pageCount = (count+pageSize-1)/pageSize;
                result.setPageCount(pageCount);
                query.skip((long) (pageIndex - 1) * pageSize).limit(pageSize);
                Sort sort = Sort.by(new Sort.Order(Sort.Direction.DESC, IotConstant.FIELD_TIME));
                query.with(sort);
                List<ElevatorAlarmDoc> data = mongoTemplate.find(query,getClazz());
                if(data.size() > 0){
                    List<ElevatorAlarmDTO> rows = data.stream().map(ElevatorAlarmDoc::toDTO).collect(Collectors.toList());
                    result.setRows(rows);
                }
            }
            return result;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    统计最近七天趋势

    public List<AlarmResultDTO> getAlarmWeekTrend(DeviceCodeQueryDTO param) {
            /*
             * db.getCollection("elevator_alarm").aggregate([ { "$match" : { "deviceCode" : "1589581864182480897"}}, { "$match" : { "timestamp" : { "$gte" : new Date("2022-11-02 00:00:00" ) } } }, { "$match" : { "timestamp" : { "$lte" : new Date("2022-11-08 23:59:59" )} } }, { "$project" : { "timestamp" : 1, "date" : { "$dateToString" : { "format" : "%Y-%m-%d", "date" : "$timestamp"}}}}, { "$group" : { "_id" : "$date", "count" : { "$sum" : 1}}}, { "$project" : { "count" : 1, "date" : "$_id"}}, { "$sort" : { "date" : 1}} ])
             */
            String deviceCode = param.getDeviceCode();
            DateTime today = DateUtil.date();
            DateTime startDate = DateUtil.parseDateTime(DateUtil.offsetDay(today,-7).toDateStr()+" 00:00:00");
            DateTime endDate = DateUtil.parseDateTime(today.toDateStr()+" 23:59:59");
            // 如下两种方式都可以
            //ProjectionOperation return1 = Aggregation.project(IotConstant.FIELD_TIME).andExpression("{$dateToString:{ format:'%Y-%m-%d',date: '$timestamp', timezone: 'Asia/Shanghai'}}").as("date");
            ProjectionOperation return1 = Aggregation.project(IotConstant.FIELD_TIME).and(DateOperators.DateToString.dateOf(IotConstant.FIELD_TIME).toString("%Y-%m-%d")).as("date");
            // 返回参数2,//如果不加这条,输出的结果如: [{"count": 3, "_id": "2019-12-13"}]
            ProjectionOperation return2 = Aggregation.project("count").and("_id").as("date");
            GroupOperation group = Aggregation.group("date").count().as("count");
            Aggregation aggregation = Aggregation.newAggregation(
    
                    //where条件
                    Aggregation.match(Criteria.where(IotConstant.FIELD_DEVICE_CODE).is(deviceCode)),
                    //时间范围
                    Aggregation.match(Criteria.where(IotConstant.FIELD_TIME).gte(startDate)),
                    Aggregation.match(Criteria.where(IotConstant.FIELD_TIME).lte(endDate)),
                    //将时间戳格式化并重命名
                    //Aggregation.project("date").andExpression("{$dateToString: {date: { $add: {'$createTime', [0]} }, format: '%Y-%m-%d'}}", new Date(28800000)).as("date"),
                    return1,
                    // 返回参数
                    //分组统计
                    group,
                    return2,
    
                    //加上为:                   [{"count": 3, "date": "2019-12-13"}]
    //                Aggregation.project("date", "count").and("date").previousOperation(),
                    //排序
                    Aggregation.sort(Sort.Direction.ASC, "date"));
    
    
            // 分组聚合查询
            AggregationResults<AlarmResultDTO> aggregate = mongoTemplate.aggregate(aggregation,
                    ElevatorAlarmDoc.class, AlarmResultDTO.class);
            // 获取结果
            List<AlarmResultDTO> list = aggregate.getMappedResults();
            List<AlarmResultDTO> result = new ArrayList<>();
            Map<String,Long> resultMap = new HashMap<>();
            if(list.size() > 0){
                list.forEach(i->{resultMap.put(i.getDate(),i.getCount());});
            }
            for(int i = 0;i<7;i++){
                DateTime d = startDate.offsetNew(DateField.DAY_OF_YEAR,i+1);
                AlarmResultDTO item = new AlarmResultDTO();
                item.setDate(d.toDateStr());
                Long count = resultMap.get(d.toDateStr());
                item.setCount(count == null?0:count);
                result.add(item);
            }
            log.info("趋势:{}",result);
            return result;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
  • 相关阅读:
    力扣-H指数
    【OpenCV图像处理9】图像金字塔
    一次不完整的渗透
    深度学习推荐系统--协同过滤推荐算法+实现代码
    STC51单片机28——跑马灯
    [论文精读]Semi-Supervised Classification with Graph Convolutional Networks
    Java IO包中System.in,System.out,System.err简介说明
    uni-app问题记录
    工业镜头接口类型
    谈谈什么是缓存穿透,缓存击穿,缓存雪崩?怎么解决?
  • 原文地址:https://blog.csdn.net/Blueeyedboy521/article/details/127622743