非关系型数据库MongoDB(文档型数据库)介绍与使用实例

news/2024/9/23 7:22:34/

MongoDB介绍

        MongoDB是一种开源的文档型数据库管理系统,它使用类似于JSON的BSON格式(Binary JSON)来存储数据。与传统关系型数据库不同,MongoDB不使用表和行的结构,而是采用集合(Collection)(Mysql表)和文档(Document)(MySql行的概念来组织数据。

  • MongoDB是一个基于分布式文件存储的数据库
  • 由C++语言编写,旨在为WEB应用提供可扩展的高性能数据存储解决方案。
  • MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。
  • 它支持的数据结构非常松散,是类似json的bson格式,因此可以存储比较复杂的数据类型
  • Mongo最大的特点是它支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引

MongoDB的主要特点包括:

1. 强大的灵活性:MongoDB的文档模型允许存储不同结构的数据,使用者可以轻松地添加、修改和删除字段,而无需进行复杂的模式迁移。

2. 高性能:MongoDB支持水平扩展,可以实现高并发和大规模的数据处理。它还提供了索引和查询优化等功能,以提高读取和写入的性能。

3. 高可用性:MongoDB支持主从复制和分片的特性,可以实现数据的备份和故障恢复。当主节点出现故障时,系统可以自动切换为备用节点来提供服务。

4. 丰富的查询语言:MongoDB使用类似于SQL的查询语言来进行数据的查询和聚合操作。同时,它还提供了地理空间查询和全文索引等功能,以满足各种复杂的查询需求。

使用场景

MongoDB是一种非关系型数据库,适用于许多不同的使用场景。以下是一些常见的

网站数据存储

        实时应用:MongoDB 非常适合需要频繁插入、更新和查询的实时应用程序,比如新闻feed、博客、论坛、评论系统等,其快速的写入速度和高效的查询性能有利于应对高并发访问。

游戏开发

        游戏用户信息:存储玩家账户、角色属性、装备、积分等数据,内嵌文档结构能很好地满足这类复杂且动态变化的数据需求。

        实时数据分析:游戏事件日志、实时排行榜等场景要求数据库具备快速写入和即时查询的能力。

物流与电商

        订单管理:订单信息、商品库存、交易历史等,MongoDB 对频繁更新的状态跟踪表现优秀。

        用户行为分析:记录并分析用户浏览、购买、搜索等行为数据。

社交网络

        用户资料与社交关系:存储用户个人信息、好友列表、消息记录等半结构化数据。

        地理位置服务:利用地理空间索引轻松实现附近的用户、地点查找功能。

物联网(IoT)

        设备数据存储:收集来自各种智能设备的实时或周期性上报的数据,如温度、湿度、状态变化等信息。

        日志记录与分析:处理大量的设备日志数据,进行多维度分析和实时监控。

内容管理系统

        博客文章、多媒体内容存储:支持大文本、富媒体类型的内容存储,同时方便实现内容标签、分类等关联查询。

视频直播和流媒体

        用户活动记录:存储用户观看历史、互动行为(如送礼、弹幕)等信息。

        实时统计与计费:对用户活动数据进行实时统计和计费计算。

缓存系统

        高性能缓存:作为高速缓存层,存储经常访问但不需永久保存或可以容忍短时间丢失的数据。

大数据分析

        聚合框架:MongoDB 内置了强大的聚合管道功能,可以在数据库层面完成数据预处理和初步分析。

 关键名词

在 MongoDB 中有三个比较重要的名词:数据库集合文档

数据库 (Database)

        在 MongoDB 中,数据库是最顶层的逻辑容器,它包含一组集合(collections)。每个 MongoDB 实例可以包含多个数据库,而且数据库之间相互独立,互不影响。

集合 (Collection)

        集合类似于关系型数据库中的表,它是 MongoDB 中存储文档的容器。集合中的文档不需要预先定义 schema(模式),也就是说,同一个集合中的文档可以有不同的字段结构。每个集合中的文档都有唯一的 _id 字段作为主键标识符。例如,usersorders 都可以是集合名,它们分别存储用户信息或订单数据。

文档 (Document)

        文档是 MongoDB 中的基本数据单元,它对应于关系型数据库中的行。文档是以 BSON(Binary JSON)格式存储的数据结构,类似于 JSON 对象,支持嵌套结构和数组。每个文档包含多个键值对,键为字符串,值可以是各种数据类型,包括其他文档、数组和其他复杂结构。例如,一个用户文档可能如下所示:

MongoDB 使用 

引用依赖包

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

配置文件配置mongodb资料(.property文件)

# MongoDB连接信息
spring.data.mongodb.host = 192.168.23.27
spring.data.mongodb.port = 27017
spring.data.mongodb.database = mall
spring.data.mongodb.auto-index-creation = true

准备对象Person

@Document(collection = "person") // 指定集合名称,就是类似mysql的表,如果不指定就以类名称作为集合名称
@Data
public class Person {@Id // 文档id, 很重要,类似mysql表的主键private Long id;private String name;private Integer age;/*** 创建一个10秒之后文档自动删除的索引 结合 spring.data.mongodb.auto-index-creation = true 一起使用创建一个10秒之后文档自动删除, 类似 redis ttl
注意:这个字段必须是date类型或者是一个包含date类型值的数组字段,一般我们使用date类型;*/@Indexed(expireAfterSeconds=10)private LocalDateTime createTime;
}

新增文档 

 @Autowiredprivate MongoTemplate mongoTemplate;/*** 插入文档*/@Testvoid insert() {Person person =new Person();person.setId(20530712L);person.setName("张三");person.setAge(26);mongoTemplate.insert(person);}/*** 自定义集合,插入文档*/@Testpublic void insertCustomCollection() throws Exception {Person person =new Person();person.setId(20530712L);person.setName("张三");person.setAge(26);person.setCreateTime(LocalDateTimeUtil.now());mongoTemplate.insert(person, "custom_person");}/*** 批量插入文档*/@Testpublic void insertBatch() throws Exception {List<Person> personList = new ArrayList<>();for (int i = 1; i < 5; i++) {Person person =new Person();person.setId((long) i);person.setName("张三"+i);person.setAge(26);person.setCreateTime(LocalDateTimeUtil.now());personList.add(person);}//mongoTemplate.insert(personList, "custom_person");mongoTemplate.insertAll(personList);}/*** 存储文档,如果没有插入,否则更新* 在存储文档的时候会通过主键 ID 进行判断,如果存在就更新,否则就插入*/@Testpublic void save() throws Exception {Person person =new Person();person.setId(1L);person.setName("张三33");person.setAge(26);person.setCreateTime(LocalDateTimeUtil.now());mongoTemplate.save(person);}

修改文档

 @Autowiredprivate MongoTemplate mongoTemplate;/*** 更新文档,匹配查询到的文档数据中的第一条数据* @throws Exception*/@Testpublic void update1() throws Exception {//更新条件Query query= new Query(Criteria.where("id").is(2));//更新值Update update= new Update().set("name", person.getName()).set("age", 32);//更新查询满足条件的文档数据(第一条)UpdateResult result =mongoTemplate.updateFirst(query, update, Person.class);System.out.println("更新条数:" + result.getMatchedCount());}/*** 更新文档,匹配查询到的文档数据中的所有数据*/@Testpublic void updateMany() throws Exception {//更新年龄大于等于32的人Query query= new Query(Criteria.where("age").gte(18));//更新姓名为 “我成人了”Update update= new Update().set("name", "我成人了");//更新查询满足条件的文档数据(全部)UpdateResult result = mongoTemplate.updateMulti(query, update, Person.class);System.out.println("更新条数:" + result.getMatchedCount());}

删除文档

@Autowiredprivate MongoTemplate mongoTemplate;/*** 删除符合条件的所有文档*/@Testpublic void remove() throws Exception {//删除年龄小于18的所有人Query query = new Query(Criteria.where("age").lt(18));DeleteResult result = mongoTemplate.remove(query, Person.class);System.out.println("删除条数:" + result.getDeletedCount());}/*** 删除符合条件的单个文档,并返回删除的文档*/@Testpublic void findAndRemove() throws Exception {Query query = new Query(Criteria.where("id").is(1L));Person result = mongoTemplate.findAndRemove(query, Person.class);System.out.println("删除的文档数据:" + result);}/*** 删除符合条件的所有文档,并返回删除的文档*/@Testpublic void findAllAndRemove() throws Exception {// 使用 in 删除 符合条件的多条文档,并返回Query query = new Query(Criteria.where("id").in(1,2,3));List<Person> result = mongoTemplate.findAllAndRemove(query, Person.class);System.out.println("删除的文档数据:" + result.toString());}

查询文档

原生查询

db.getCollection("my_person").find({ name: /^张/ ,name: /大$/})db.getCollection("my_person").find({ name: /^张/,age:{$lte:12}})

Java实现

@Autowiredprivate MongoTemplate mongoTemplate;/*** 查询集合中的全部文档数据*/@Testpublic void findAll()  {List<Person> result = mongoTemplate.findAll(Person.class);System.out.println("查询结果:" + result.toString());}/*** 查询集合中指定的ID文档数据*/@Testpublic void findById() {long id = 2L;Person result = mongoTemplate.findById(id, Person.class);System.out.println("查询结果:" + result.toString());}/*** 根据条件查询集合中符合条件的文档,返回第一条数据*/@Testpublic void findOne() {Query query = new Query(Criteria.where("name").is("张三3"));Person result = mongoTemplate.findOne(query, Person.class);System.out.println("查询结果:" + result.toString());}/*** 根据条件查询所有符合条件的文档*/@Testpublic void findByCondition() {Query query = new Query(Criteria.where("age").gt(18));List<Person> result = mongoTemplate.find(query, Person.class);System.out.println("查询结果:" + result.toString());}/*** 根据【AND】关联多个查询条件,查询集合中所有符合条件的文档数据*/@Testpublic void findByAndCondition() {// 创建条件Criteria name = Criteria.where("name").is("张三");Criteria age = Criteria.where("age").is(18);// 创建条件对象,将上面条件进行 AND 关联Criteria criteria = new Criteria().andOperator(name, age);// 创建查询对象,然后将条件对象添加到其中Query query = new Query(criteria);List<Person> result = mongoTemplate.find(query, Person.class);System.out.println("查询结果:" + result.toString());}/*** 根据【OR】关联多个查询条件,查询集合中的文档数据*/@Testpublic void findByOrCondition() {// 创建条件Criteria criteriaUserName = Criteria.where("name").is("张三");Criteria criteriaPassWord = Criteria.where("age").is(22);// 创建条件对象,将上面条件进行 OR 关联Criteria criteria = new Criteria().orOperator(criteriaUserName, criteriaPassWord);// 创建查询对象,然后将条件对象添加到其中Query query = new Query(criteria);List<Person> result = mongoTemplate.find(query, Person.class);System.out.println("查询结果:" + result.toString());}/*** 根据【IN】关联多个查询条件,查询集合中的文档数据*/@Testpublic void findByInCondition() {// 设置查询条件参数List<Long> ids = Arrays.asList(10L, 11L, 12L);// 创建条件Criteria criteria = Criteria.where("id").in(ids);// 创建查询对象,然后将条件对象添加到其中Query query = new Query(criteria);List<Person> result = mongoTemplate.find(query, Person.class);System.out.println("查询结果:" + result.toString());}/*** 根据【逻辑运算符】查询集合中的文档数据*/@Testpublic void findByOperator() {// 设置查询条件参数int min = 20;int max = 35;Criteria criteria = Criteria.where("age").gt(min).lte(max);// 创建查询对象,然后将条件对象添加到其中Query query = new Query(criteria);List<Person> result = mongoTemplate.find(query, Person.class);System.out.println("查询结果:" + result.toString());}/*** 根据【正则表达式】查询集合中的文档数据*/@Testpublic void findByRegex() {// 设置查询条件参数String regex = "^张";Criteria criteria = Criteria.where("name").regex(regex);// 创建查询对象,然后将条件对象添加到其中Query query = new Query(criteria);List<Person> result = mongoTemplate.find(query, Person.class);System.out.println("查询结果:" + result.toString());}/*** 根据条件查询集合中符合条件的文档,获取其文档列表并排序*/@Testpublic void findByConditionAndSort() {Query query = new Query(Criteria.where("name").is("张三")).with(Sort.by("age"));List<Person> result = mongoTemplate.find(query, Person.class);System.out.println("查询结果:" + result.toString());}/*** 根据单个条件查询集合中的文档数据,并按指定字段进行排序与限制指定数目*/@Testpublic void findByConditionAndSortLimit() {String userName = "张三";//从第5行开始,查询3条数据返回Query query = new Query(Criteria.where("name").is("张三")).with(Sort.by("createTime")).limit(3).skip(5);List<Person> result = mongoTemplate.find(query, Person.class);System.out.println("查询结果:" + result.toString());}/*** 统计集合中符合【查询条件】的文档【数量】*/@Testpublic void countNumber() {// 设置查询条件参数String regex = "^张*";Criteria criteria = Criteria.where("name").regex(regex);// 创建查询对象,然后将条件对象添加到其中Query query = new Query(criteria);long count = mongoTemplate.count(query, Person.class);System.out.println("统计结果:" + count);}

创建索引

@Autowiredprivate MongoTemplate mongoTemplate;/*** 创建升序索引*/@Testpublic void createAscendingIndex() {// 设置字段名称String field = "age";// 创建索引mongoTemplate.getCollection("person").createIndex(Indexes.descending(field));}/*** 根据索引名称移除索引*/@Testpublic void removeIndex() {// 设置字段名称String field = "age_1";// 删除索引mongoTemplate.getCollection("person").dropIndex(field);}/*** 查询集合中所有的索引*/@Testpublic void getIndexAll() {// 获取集合中所有列表ListIndexesIterable<Document> indexList =   mongoTemplate.getCollection("person").listIndexes();// 获取集合中全部索引信息for (Document document : indexList) {System.out.println("索引列表:" + document);}}


http://www.ppmy.cn/news/1514772.html

相关文章

鸿蒙内核源码分析(特殊进程篇)

三个进程 鸿蒙有三个特殊的进程&#xff0c;创建顺序如下: 2号进程&#xff0c;KProcess&#xff0c;为内核态根进程.启动过程中创建.0号进程&#xff0c;KIdle为内核态第二个进程&#xff0c;它是通过KProcess fork 而来的.这有点难理解.1号进程&#xff0c;init&#xff0c…

产品经理-​​实习中的自我迭代(41)

实习中的自我迭代,优秀实习生必备素质 跟大家认识了之后&#xff0c;就要开始做事情了&#xff0c;那我们怎么做一个优秀的实习生呢&#xff1f;以下几点作为参考。 1. 目标明确 知道自己的工作为什么要做&#xff0c;要做到什么程度&#xff0c;目前存在什么问题&#xff0c;该…

k8s上部署rancher

一、什么事rancher Rancher 是一个 Kubernetes 管理工具&#xff0c;让你能在任何地方和任何提供商上部署和运行集群。 Rancher 可以创建来自 Kubernetes 托管服务提供商的集群&#xff0c;创建节点并安装 Kubernetes&#xff0c;或者导入在任何地方运行的现有 Kubernetes 集…

Python中常见数据结构

文章目录 1. 列表&#xff08;List&#xff09;2. 元组&#xff08;Tuple&#xff09;3. 字典&#xff08;Dictionary&#xff09;4. 集合&#xff08;Set&#xff09;5. 数组&#xff08;Array&#xff09;6. 栈&#xff08;Stack&#xff09;7. 队列&#xff08;Queue&#x…

vue vite创建项目步骤

1. 创建vue项目 node版本需18以上 不然报错 npm init vuelatest2. 项目配置 配置项目的icon配置项目的标题配置jsconfig.json 3. 项目目录结构划分 4.css样式的重置 npm install normalize.cssreset.css html {line-height: 1.2; }body, h1, h2, h3, h4, ul, li {padding…

linux28学习 进程结束演示

signal.c #include <stdio.h> #include <signal.h> #include<unistd.h> void handler(int sig) { printf("catch a sig : %d\n", sig); } int main() { while(1){sleep(1);printf("进程号&#xff1a;%d\n",getpid());}return 0; }…

C++ 设计模式——单例模式

单例模式 C 设计模式——单例模式1. 单例模式的基本概念与实现2. 多线程环境中的问题3. 内存管理问题1. 内存泄漏风险2. 自动释放策略3. 垃圾回收机制4. 嵌套类与内存管理 4. UML 图UML 图解析 优缺点适用场景总结 C 设计模式——单例模式 单例模式&#xff08;Singleton Patt…

MySQL:this is incompatible with sql_mode=only_full_group_by

错误场景 有时候&#xff0c;遇到数据库重复数据&#xff0c;需要将数据进行分组&#xff0c;并取出其中一条来展示&#xff0c;这时就需要用到group by语句。 但是&#xff0c;如果mysql是高版本&#xff0c;当执行group by时&#xff0c;select的字段不属于group by的字段的…