MongoDB学习记录
RDMS和mongo的术语对应关系
mongo数据类型
Springboot整合实操
概念
什么是mongoDB
MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB 文档类似于 JSON 对象
-
为什么使用mongodb
- 对数据库高并发读写。
- 对海量数据的高效率存储和访问。
- 对数据库的高可扩展性和高可用性。
-
mongodb那些方面比较弱
- 数据库事务一致性需求
- 数据库的写实时性和读实时性需求
- 对复杂的SQL查询,特别是多表关联查询的需求
-
mongodb的特点
1、MongoDB 是一个面向文档存储的数据库,操作起来比较简单和容易。
2、你可以在MongoDB记录中设置任何属性的索引 (如:FirstName="Sameer",Address="8 Gandhi Road")来实现更快的排序。
3、你可以通过本地或者网络创建数据镜像,这使得MongoDB有更强的扩展性。
4、如果负载的增加(需要更多的存储空间和更强的处理能力) ,它可以分布在计算机网络中的其他节点上这就是所谓的分片。
5、Mongo支持丰富的查询表达式。查询指令使用JSON形式的标记,可轻易查询文档中内嵌的对象及数组。
6、MongoDb 使用update()命令可以实现替换完成的文档(数据)或者一些指定的数据字段 。
7、Mongodb中的Map/reduce主要是用来对数据进行批量处理和聚合操作。
8、Map和Reduce。Map函数调用emit(key,value)遍历集合中所有的记录,将key与value传给Reduce函数进行处理。
9、Map函数和Reduce函数是使用Javascript编写的,并可以通过db.runCommand或mapreduce命令来执行MapReduce操作。
10、GridFS是MongoDB中的一个内置功能,可以用于存放大量小文件。
11、MongoDB允许在服务端执行脚本,可以用Javascript编写某个函数,直接在服务端执行,也可以把函数的定义存储在服务端,下次直接调用即可。
12、MongoDB支持各种编程语言:RUBY,PYTHON,JAVA,C++,PHP,C#等多种语言。
13、MongoDB安装简单。
RDMS和mongo的术语对应关系
| SQL术语/概念 | MongoDB术语/概念 | 解释/说明 |
|---|---|---|
| database | database | 数据库 |
| table | collection | 数据库表/集合 |
| row | document | 数据记录行/文档 |
| column | field | 数据字段/域 |
| index | index | 索引 |
| table joins | 表连接,MongoDB不支持 | |
| primary key | primary key | 主键,MongoDB自动将_id字段设置为主键 |
monogdb的数据类型
| 数据类型 | 描述 |
|---|---|
| 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 | 正则表达式类型。用于存储正则表达式。 |
mongoDb的适用场景
适用场景
1、网站数据:Mongo非常适合实时的插入,更新与查询,并具备网站实时数据存储所需的复制及高度伸缩性。
2、缓存:由于性能很高,Mongo也适合作为信息基础设施的缓存层。在系统重启之后,由M ongo搭建的持久化缓存层可以避免下层的数据源过载。
3、大尺寸,低价值的数据:使用传统的关系型数据库存储一些数据时可能会比较昂贵, 在此之前,很多时候程序员往往会选择传统的文件进行存储。
4、高伸缩性的场景:Mongo非常适合由数十或数百台服务器组成的数据库。Mongo的路线图中已经包含对Map Reduce弓摩的内置支持。
5、用于对象及 JSON数据的存储:Mongo的BSON数据格式非常适合文档化格式的存储 及查询。
不适用场景
1、高度事务性的系统:例如银行或会计系统。传统的关系型数据库目前还是更适用于需要大量原子性复杂事务的应用程序。
2、传统的商业智能应用:针对特定问题的BI数据库会对产生高度优化的查询方式。对于此类应用,数据仓库可能是更合适的选择。
实操
SpringBootData操作实战
-
创建maven工程
-
引入pom依赖
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <dependency> <groupId>joda-time</groupId> <artifactId>joda-time</artifactId> <version>2.10.1</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies> -
配置文件编写
spring: data: mongodb: uri: mongodb://localhost:27017/test -
基本数据类+UserRepository创建
@Data @Document("User") @Builder @AllArgsConstructor @NoArgsConstructor public class User { @Id private String id; private String name; private Integer age; private String email; private String createDate; }如果你只使用MongoTemplate的方式操作数据库的话,这个也可以不写
@Repository public interface UserRepository extends MongoRepository<User, String> { } -
测试CRUD (使用MongoTemplate)
@SpringBootTest(classes = Main.class) @RunWith(SpringRunner.class) public class MongoTemplateTests { @Autowired public MongoTemplate mongoTemplate; @Test public void testAdd(){ User user = new User(); user.setName("天龙人"); user.setAge(19); user.setEmail("asdasdasd@gamil.com"); user.setCreateDate("2017-12-02"); User row = mongoTemplate.insert(user); System.out.println(row); // System.out.println(user); } @Test public void testFind(){ // 全查 List<User> all = mongoTemplate.findAll(User.class); all.forEach(System.out::println); // 根据条件找找 Query query = new Query(Criteria.where("name").is("天龙人").and("age").lt(20)); List<User> users = mongoTemplate.find(query, User.class); users.forEach(System.out::println); // 根据id找 User user = mongoTemplate.findById("65a4d3a9116a6a34fd15f93e", User.class); System.out.println(user); // 分页查找 int pageNo = 1; int pageSize = 10; int totalCount = (int) mongoTemplate.count(query, User.class); List<User> userList = mongoTemplate.find(query.skip((pageNo - 1) * pageSize).limit(pageSize), User.class); userList.forEach(System.out::println); } // 修改 @Test public void testUpdate(){ User user = mongoTemplate.findById("65a4d3a9116a6a34fd15f93e", User.class); Update update = new Update(); update.set("name","大傻逼"); Query query = new Query(Criteria.where("id").is(user.getId())); UpdateResult upsert = mongoTemplate.upsert(query, update, User.class); long matchedCount = upsert.getMatchedCount(); System.out.println(matchedCount); } // 删除 @Test public void delete(){ Query query = new Query(Criteria.where("name").is("大傻逼")); DeleteResult row = mongoTemplate.remove(query); System.out.println(row.getDeletedCount()); } // 模糊匹配 @Test public void test(){ String name = "龙人"; 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); } } -
测试CURD (使用继承Repository的方法)
@SpringBootTest(classes = Main.class) @RunWith(SpringRunner.class) public class MongoRepositoryTests { @Autowired public UserRepository repository; // 添加 @Test public void testAdd() { User user = User.builder().name("张三").age(145).email("123712309@qq.com").build(); repository.insert(user); } // 查找 @Test public void testFind() { ExampleMatcher exampleMatcher = ExampleMatcher.matching() .withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING) .withIgnoreCase(true); User user = new User(); user.setName("三"); Example<User> userExample = Example.of(user, exampleMatcher); List<User> userList = repository.findAll(userExample); userList.forEach(System.out::println); } // 删除 @Test public void testDelete(){ User user = new User(); user.setName("张三"); repository.delete(user); } @Test public void findUsersPage() { Sort sort = Sort.by(Sort.Direction.DESC, "age"); //0为第一页 Pageable pageable = PageRequest.of(0, 10, sort); //创建匹配器,即如何使用查询条件 ExampleMatcher matcher = ExampleMatcher.matching() //构建对象 .withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING) //改变默认字符串匹配方式:模糊查询 .withIgnoreCase(true); //改变默认大小写忽略方式:忽略大小写 User user = new User(); user.setName("三"); //创建实例 Example<User> example = Example.of(user, matcher); Page<User> pages = repository.findAll(example, pageable); System.out.println(pages); } }
SpringData操作实战中,使用template的方式会更加灵活方便,但是关于模糊匹配需要用到正则,通过继承repository的方式操作起来不灵活,但是分页和模糊匹配支持的很好。一般综合起来使用
900cad0d-9f70-4ece-bc87-7bf74555f573