zoukankan      html  css  js  c++  java
  • MongoDB入门使用

    1. 什么是MongoDB

    MongoDB 是一个基于分布式文件存储的数据库。由 C++ 语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。
    MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。
    MongoDB 支持的数据结构非常松散,是类似json的bson格式,因此可以存储比较复杂的数据类型。

    1.1 MongoDB与Mysql区别

    1.2 MongoDB的使用场景

    参考:https://mongoing.com/archives/3609

    • 案例1
      用在应用服务器的日志记录,查找起来比文本灵活,导出也很方便。也是给应用练手,从外围系统开始使用MongoDB。
      用在一些第三方信息的获取或者抓取,因为MongoDB的schema-less,所有格式灵活,不用为了各种格式不一样的信息专门设计统一的格式,极大得减少开发的工作。

    • 案例2
      mongodb之前有用过,主要用来存储一些监控数据,No schema 对开发人员来说,真的很方便,增加字段不用改表结构,而且学习成本极低。

    • 案例3
      使用MongoDB做了O2O快递应用,·将送快递骑手、快递商家的信息(包含位置信息)存储在 MongoDB,然后通过 MongoDB 的地理位置查询,这样很方便的实现了查找附近的商家、骑手等功能,使得快递骑手能就近接单,目前在使用MongoDB 上没遇到啥大的问题,官网的文档比较详细,很给力。

    经常跟一些同学讨论 MongoDB 业务场景时,会听到类似『你这个场景 mysql 也能解决,没必要一定用 MongoDB』的声音,的确,并没有某个业务场景必须要使用 MongoDB才能解决,但使用 MongoDB 通常能让你以更低的成本解决问题(包括学习、开发、运维等成本),下面是 MongoDB 的主要特性,大家可以对照自己的业务需求看看,匹配的越多,用 MongoDB 就越合适。

    从目前阿里云 MongoDB 云数据库上的用户看,MongoDB 的应用已经渗透到各个领域,比如游戏、物流、电商、内容管理、社交、物联网、视频直播等,以下是几个实际的应用案例:

    • 游戏场景,使用 MongoDB 存储游戏用户信息,用户的装备、积分等直接以内嵌文档的形式存储,方便查询、更新
    • 物流场景,使用 MongoDB 存储订单信息,订单状态在运送过程中会不断更新,以 MongoDB 内嵌数组的形式来存储,一次查询就能将订单所有的变更读取出来。
    • 社交场景,使用 MongoDB 存储存储用户信息,以及用户发表的朋友圈信息,通过地理位置索引实现附近的人、地点等功能
    • 物联网场景,使用 MongoDB 存储所有接入的智能设备信息,以及设备汇报的日志信息,并对这些信息进行多维度的分析
    • 视频直播,使用 MongoDB 存储用户信息、礼物信息等
    • ……

    如果你还在为是否应该使用 MongoDB,不如来做几个选择题来辅助决策(注:以下内容改编自 MongoDB 公司 TJ 同学的某次公开技术分享)。
    如果以下有1个 Yes,可以考虑 MongoDB,2个及以上的 Yes,选择 MongoDB 绝不会后悔。




    2. MongoDB概念解析

    SQL术语/概念 MongoDB术语/概念 解释/说明
    database database 数据库
    table collection 数据库表/集合
    row document 数据记录行/文档
    column field 数据字段/域
    index index 索引
    table joins 表连接,MongoDB不支持多表连接
    primary key primary key 主键,MongoDB自动将_id字段设置为主键

    2.1 数据库【一个mongodb中可以建立多个数据库】

    1、 Help查看命令提示 
    db.help();
    2、 切换/创建数据库
    use test
    如果数据库不存在,则创建数据库,否则切换到指定数据库
    3、 查询所有数据库 
    show dbs;
    4、 删除当前使用数据库 
    db.dropDatabase();
    5、 查看当前使用的数据库 
    db.getName();
    6、 显示当前db状态 
    db.stats();
    7、 当前db版本 
    db.version();
    8、 查看当前db的链接机器地址 
    db.getMongo();
    

    2.2 文档【文档是一组键值(key-value)对,即(BSON)】

    2.3 集合【集合就相当于Mysql中的一张表】

    集合没有固定的结构,这意味着你在对集合可以插入不同格式和类型的数据,但通常情况下我们插入集合的数据都会有一定的关联性。

    1、 创建一个集合(table)
    db.createCollection( "collName");
    2、 得到指定名称的集合(table )
    db.getCollection("user");
    

    2.4 支持的数据类型

    数据类型 描述
    String 字符串。存储数据常用的数据类型。在 MongoDB 中,UTF-8 编码的字符串才是合法的。
    Integer 整型数值。用于存储数值。根据你所采用的服务器,可分为 32 位或 64 位。
    Boolean 布尔值。用于存储布尔值(真/假)。
    Double 双精度浮点值。用于存储浮点值。
    Min/Max keys 将一个值与 BSON(二进制的 JSON)元素的最低值和最高值相对比。
    Arrays 用于将数组或列表或多个值存储为一个键。
    Timestamp 时间戳。记录文档修改或添加的具体时间。
    Object 用于内嵌文档。
    Null 用于创建空值。
    Symbol 符号。该数据类型基本上等同于字符串类型,但不同的是,它一般用于采用特殊符号类型的语言。
    Date 日期时间。用 UNIX 时间格式来存储当前日期或时间。你可以指定自己的日期时间:创建 Date 对象,传入年月日信息。
    Object ID 对象 ID。用于创建文档的 ID。
    Binary Data 二进制数据。用于存储二进制数据。
    Code 代码类型。用于在文档中存储 JavaScript 代码。
    Regular expression 正则表达式类型。用于存储正则表达式。


    3. MongoDB入门

    3.1 Insert


    插入后自动帮我们创建了id,创建id的类型为Objectld【默认】
    Objectld使用12字节的存储空间,每个字节二位十六进制数字, 是一个24位的字符串

    • 时间戳:时间不断变化的
    • 机器:主机的唯_标识码。通常是机器主机名的散列值,这样可以确保不同主机 生成不同的Objectld ,不产生冲突。
    • PID:为了确保在同一台机器上并发的多个进程产生的Objectld是唯一的,所以加上进程标识符(PID).
    • 计数器:前9个字节保证了同一秒钟不同机器不同进程产生的Objectld是唯一的。 后3个字节就是一个自动增加的计数器,确保相同进程同一秒产生的Objectld也是不一样。同一秒最多允许每个进程拥有IS 777 2托个不同的Objectld。

    3.2 Query

    3.2.1 where
    # select * from User where name = 'zhangsan'
    
    > db.User.find({name:"zhangsan"})
    
    3.2.2 fields【指定列】
    # select name, age from User where age = 21
    
    > db.User.find({age:21}, {'name':1, 'age':1})
    
    3.2.3 sort
    # select * from User order by age
    
    > db.User.find().sort({age:1})
    
    //sort() 方法可以通过参数指定排序的字段,并使用 1 和 -1 来指定排序的方式.
    //其中 1 为升序排列,而 -1 是用于降序排列。
    
    3.2.4 in
    # select * from User where age in (21, 26, 32)
    
    > db.User.find({age:{$in:[21,26,32]}})
    
    3.2.5 count
    # select count(*) from User where age >20
    
    > db.User.find({age:{$gt:20}}).count()
    
    3.2.6 or
    # select * from User where age = 21 or age = 28
    
    > db.User.find({$or:[{age:21}, {age:28}]})
    
    3.2.7 limit
    # select * from User skip 2 limit 3
    
    > db.User.find().skip(0).limit(3)
    
    //在 MongoDB 中使用 limit()方法来读取指定数量的数据,skip()方法来跳过指定数量的数据。
    

    3.3 Update

    # update Userset age = 100, sex = 0 where name = 'user1'
    
    > db.User.update({name:"zhangsan"}, {$set:{age:100, sex:0}})
    
    Update()有几个参数需要注意。
      db.collection.update(criteria, objNew, upsert, mult)
    
        criteria:需要更新的条件表达式
        objNew:更新表达式
        upsert:如FI标记录不存在,是否插入新文档。 
        multi:是否更新多个文档。
    

    3.4 Remove

    > db.User.remove(id)
    //移除对应id的行
    
    > db.User.remove({})
    //移除所有
    

    3.5 聚合操作

    3.6 索引

    >db.User.createIndex({"name":1})
    
    //name值为你要创建的索引字段,1 为指定按升序创建索引,如果你想按降序来创建索引指定为 -1 即可
    


    4. SpringBoot集成MongoDB

    spring-data-mongodb提供了MongoTemplate与MongoRepository两种方式:
    方式一:MongoRepository 操作简单
    方式二:MongoTemplate 操作灵活

    4.1 添加依赖

    <dependency>
         <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-mongodb</artifactId>
    </dependency>
    

    4.2 添加配置

    spring.data.mongodb.uri=mongodb://47.93.118.241:27017/test
    

    4.3 添加实体

    @Data
    @Document("User")
    public class User {
    
     @Id
     private String id;
     private String name;
     private Integer age;
     private String email;
     private String createDate;
    }
    

    4.4 基于MongoTemplate开发CRUD

    mongoTemplate常用方法:

        mongoTemplate.findAll(User.class): 查询User文档的全部数据
        mongoTemplate.findById(<id>, User.class): 查询User文档id为id的数据
        mongoTemplate.find(query, User.class);: 根据query内的查询条件查询
        mongoTemplate.upsert(query, update, User.class): 修改
        mongoTemplate.remove(query, User.class): 删除
        mongoTemplate.insert(User): 新增
    
        Query对象
          1、创建一个query对象(用来封装所有条件对象),再创建一个criteria对象(用来构建条件)  
          2、精准条件:criteria.and(“key”).is(“条件”)     模糊条件:criteria.and(“key”).regex(“条件”)
          3、封装条件:query.addCriteria(criteria)
          4、大于(创建新的criteria):Criteria gt = Criteria.where(“key”).gt(“条件”)小于(创建新的criteria):Criteria lt = Criteria.where(“key”).lt(“条件”)
          5、Query.addCriteria(new Criteria().andOperator(gt,lt));
          6、一个query中只能有一个andOperator()。其参数也可以是Criteria数组。
          7、排序 :query.with(new Sort(Sort.Direction.ASC, "age"). and(new Sort(Sort.Direction.DESC, "date")))
    
    @SpringBootTest
    class DemomogoApplicationTests {
    	
    	@Autowired
    	private MongoTemplate mongoTemplate;
    	
    	//添加
    	@Test
    	public void createUser() {
    		User user = new User();
    		user.setAge(20);
    		user.setName("test");
    		user.setEmail("4932200@qq.com");
    		User user1 = mongoTemplate.insert(user);
    		System.out.println(user1);
    	}
    	
    	//查询所有
    	@Test
    	public void findUser() {
    		List<User> userList = mongoTemplate.findAll(User.class);
    		System.out.println(userList);
    	}
    	
    	//根据id查询
    	@Test
    	public void getById() {
    		User user =
    			mongoTemplate.findById("5ffbfa2ac290f356edf9b5aa", User.class);
    		System.out.println(user);
    	}
    	
    	//条件查询
    	@Test
    	public void findUserList() {
    		Query query = new Query(Criteria.where("name").is("test").and("age").is(20));
    		List<User> userList = mongoTemplate.find(query, User.class);
    		System.out.println(userList);
    	}
    	
    	//模糊查询
    	@Test
    	public void findUsersLikeName() {
    		String name = "est";
    		String regex = String.format("%s%s%s", "^.*", name, ".*$");
    		Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
    		Query query = new Query(Criteria.where("name").regex(pattern));
    		List<User> userList = mongoTemplate.find(query, User.class);
    		System.out.println(userList);
    	}
    	
    	//分页查询
    	@Test
    	public void findUsersPage() {
    		String name = "est";
    		int pageNo = 1;
    		int pageSize = 10;
    		
    		Query query = new Query();
    		String regex = String.format("%s%s%s", "^.*", name, ".*$");
    		Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
    		query.addCriteria(Criteria.where("name").regex(pattern));
    
                    // 记录数
    		int totalCount = (int) mongoTemplate.count(query, User.class);
                    // 分页
    		List<User> userList = mongoTemplate.find(query.skip((pageNo - 1) * pageSize).limit(pageSize), User.class);
    		
    		Map<String, Object> pageMap = new HashMap<>();
    		pageMap.put("list", userList);
    		pageMap.put("totalCount", totalCount);
    		System.out.println(pageMap);
    	}
    	
    	//修改
    	@Test
    	public void updateUser() {
    		User user = mongoTemplate.findById("5ffbfa2ac290f356edf9b5aa", User.class);
    		user.setName("test_1");
    		user.setAge(25);
    		user.setEmail("493220990@qq.com");
    		Query query = new Query(Criteria.where("_id").is(user.getId()));
    		Update update = new Update();
    		update.set("name", user.getName());
    		update.set("age", user.getAge());
    		update.set("email", user.getEmail());
    		UpdateResult result = mongoTemplate.upsert(query, update, User.class);
    		long count = result.getModifiedCount();
    		System.out.println(count);
    	}
    	
    	//删除操作
    	@Test
    	public void delete() {
    		Query query =
    			new Query(Criteria.where("_id").is("5ffbfa2ac290f356edf9b5aa"));
    		DeleteResult result = mongoTemplate.remove(query, User.class);
    		long count = result.getDeletedCount();
    		System.out.println(count);
    	}
    }
    

    4.5 基于MongoRepository开发CRUD

    ★★★★★★★★★Spring Data提供了对mongodb数据访问的支持,我们只需要继承MongoRepository类,按照Spring Data规范就可以了★★★★★★★★★★
    
    //添加Repository接口继承MongoRepository    因为MongoRepository 帮我们实现了对MongoDB的操作方法。
    @Repository
    public interface UserRepository extends MongoRepository<User, String> {
    
    }
    
    
    
    //开发CRUD
    @SpringBootTest
    class DemomogoApplicationTests1 {
    
        @Autowired
        private UserRepository userRepository;
    
        //添加
        @Test
        public void createUser() {
            User user = new User();
            user.setAge(20);
            user.setName("张三");
            user.setEmail("3332200@qq.com");
            User user1 = userRepository.save(user);   // 返回的user里面有新增的user的id
        }
    
        //查询所有
        @Test
        public void findUser() {
            List<User> userList = userRepository.findAll();
            System.out.println(userList);
        }
    
        //id查询
        @Test
        public void getById() {
            User user = userRepository.findById("5ffbfe8197f24a07007bd6ce").get();
            System.out.println(user);
        }
    
        //条件查询
        @Test
        public void findUserList() {
            User user = new User();
            user.setName("张三");
            user.setAge(20);
    
            Example<User> userExample = Example.of(user);
            List<User> userList = userRepository.findAll(userExample);
            System.out.println(userList);
        }
    
        //模糊查询
        @Test
        public void findUsersLikeName() {
            //创建匹配器,即如何使用查询条件
            ExampleMatcher matcher = ExampleMatcher.matching() //构建对象
                    .withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING) //改变默认字符串匹配方式:模糊查询
                    .withIgnoreCase(true); //改变默认大小写忽略方式:忽略大小写
    
            User user = new User();
            user.setName("三");
    
            Example<User> userExample = Example.of(user, matcher);
            List<User> userList = userRepository.findAll(userExample);
            System.out.println(userList);
        }
    
        //分页查询
        @Test
        public void findUsersPage() {
    
            //创建匹配器,即如何使用查询条件
            ExampleMatcher matcher = ExampleMatcher.matching() //构建对象
                    .withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING) //改变默认字符串匹配方式:模糊查询
                    .withIgnoreCase(true); //改变默认大小写忽略方式:忽略大小写
    
            User user = new User();
            user.setName("三");
            Example<User> userExample = Example.of(user, matcher);
    
            Sort sort = Sort.by(Sort.Direction.DESC, "age");
            //0为第一页
            Pageable pageable = PageRequest.of(0, 10, sort);
    
    
            //创建实例
            Example<User> example = Example.of(user, matcher);
            Page<User> pages = userRepository.findAll(example, pageable);
            System.out.println(pages);
        }
    
        //修改
        @Test
        public void updateUser() {
            User user = userRepository.findById("5ffbfe8197f24a07007bd6ce").get();
            user.setName("张三_1");
            user.setAge(25);
            user.setEmail("883220990@qq.com");
    
            // 如果有id 就是修改操作 否则是添加操作
            User save = userRepository.save(user);
            System.out.println(save);
        }
    
        //删除
        @Test
        public void delete() {
            userRepository.deleteById("5ffbfe8197f24a07007bd6ce");
        }
    }
    

    pring Data提供了对mongodb数据访问的支持,我们只需要继承MongoRepository类,按照Spring Data规范就可以了。


    不是随便声明的,而需要符合一定的规范。
    查询方法以find | read | get开头。
    涉及条件查询时,条件的属性用条件关键字连接。条件属性首字母需要大写
    支持属性的级联查询,但若当前类有符合条件的属性则优先使用,而不使用级联属性,若需要使用级联属性,则属性之间使用_强制进行连接。

  • 相关阅读:
    MAC配置DNS服务器
    真机IOS8.3以上的文件夹共享
    appium + python的环境配置_windows
    python 的时间与日期
    sublimetext 2 编译文件带input时 提示 EOFError: EOF when reading a line
    cmd无法输入中文解决方案
    配置python学习环境遇到的问题:[Decode error
    monkey初接触
    Android logcat输出中文乱码
    运行 命令框不记录打过的命令,重启后CMD里面是空的.上次打过的命令消失了.
  • 原文地址:https://www.cnblogs.com/itlihao/p/14559435.html
Copyright © 2011-2022 走看看