MongoDB文档整理

过往mongodb文档:

1. MongoDB前瞻


1、MongoDB概述:

  • MongoDB是一款分布式文档型数据库,底层基于C++语言编写,属于NoSQL的一种。
  • MongoDB与传统的关系型数据库相比,更加简单、语法松散,结构是key-value结构。
    • MySQL:数据库->表->记录。
    • MongoDB:数据库->集合->文档。
  • MongoDB中的文档类似JSON,结构是BSON格式(Binary JSON,二进制JSON,和 JSON 一样支持内嵌的文档对象和数组对象),每个BSON文档都可以存储不同的结构。
  • MongoDB最大的特点是它支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系型数据库单表查询的绝大部分功能,而且还支持对数据建立索引。

MongoDB中的一些概念:

RDBMS MongoDB
数据库 数据库
集合
文档
字段
表联合 嵌入文档
主键 _id

2、MongoDB:适用场景:

引入某个技术前,需要了解它的特性、适用场景以及可以解决什么问题,而不是为了技术而技术。

  • MongoDB不需要去明确指定一张表的具体结构,对字段的管理非常灵活,有很强的可扩展性。
  • 天生支持高并发、高可用、高可扩展性,自带数据压缩功能,支持海量数据的高效存储和访问。
  • 支持基本的CRUD、数据聚合、文本搜索和地理空间查询功能。

适用于:

  • 网站数据:MongoDB非常适合实时的插入,更新与查询,并具备网站实时数据存储所需的复制及高度伸缩性。

  • 高伸缩性的场景:MongoDB非常适合由数十或数百台服务器组成的数据库。

  • 大尺寸,低价值的数据:使用传统的关系型数据库存储一些数据时可能会比较昂贵,在此,之前,很多时候程序员往往会选择传统的文件进行存储。

  • 缓存:由于性能很高,MongoDB也适合作为信息基础设施的缓存层。在系统重启之后,由MongoDB搭建的持久化缓存层可以避免下层的数据源过载。

  • 例如:弹幕、直播间互动信息、朋友圈信息、定理位置、物联网(比如 接入的设备信息、设备汇报的日志信息等)、物流(订单信息、订单状态等)场景等。

不适用场景:

  • 高度事务性系统:例如银行系统。传统的关系型数据库目前还是更适用于需要大量原子性复杂事务的应用程
    序。
  • 传统的商业智能应用:针对特定问题的BI数据库会对产生高度优化的查询方式。对于此类应用,数仓可能是更合适的选择。

3、MongoDB安装:(docker方式)

sh 复制代码
#拉取镜像
docker pull mongo:7.0.0

#创建宿主机上的mongodb数据目录
rm -rf /opt/mongo
mkdir -p /opt/mongo/data/db

#启动容器
docker run -d --restart=always -p 27017:27017 --name mongo -v /opt/mongo/data/db:/data/db
mongo 7.0.0

#进入容器,连接mongo客户端
docker exec -it mongo mongosh

#基础命令
show dbs  #列出所有数据库
db.version() #当前db版本
db.getMongo() #查看当前db的连接机器地址
db.help() #帮助文档
quit() #退出命令行

2. 命令操作MongoDB


2.1、数据库的操作


1、创建数据:

如果数据库不存在,会自动创建数据库,否则就切换到指定数据库。

js 复制代码
use 库名

2、查看当前数据库:

js 复制代码
db.getName()

3、显示当前数据库状态:

js 复制代码
db.stats()

4、删除当前数据库:

js 复制代码
db.dropDatabase()

5、列出所有数据库:

sh 复制代码
show dbs 或 show databases

2.2 集合的操作


1、创建集合:(一般不需要我们手动创建,添加文档时会自动创建)

js 复制代码
db.creataCollection("集合名称/表名")

2、删除集合:

js 复制代码
db.集合名.drop()

2.3 文档的操作


文档是一组键值(key-vlue)对。MongoDB的文档不需要设置相同的字段,并且相同的字段不需要相同的数据类

型,这与关系型数据库有很大的区别,也是MongoDB非常突出的特点。

需要注意的是:MongoDB区分类型和大小写,MongoDB的文档不能有重复的键。

1、新增文档:(insert)

向User集合插入一条记录。可以预先使用createCollection方法创建集合,也可以不创建集合,直接插入数据,那么集合会被自动创建。

js 复制代码
db.user.insert({name:'张三',age:21,sex:true})

相关文档:https://www.runoob.com/mongodb/mongodb-insert.html

2、查询文档:(query)

查询当前User集合中所有的记录:

js 复制代码
db.user.find()

查询当前User集合中name是张三的记录:(大括号里指定查询条件,是键值对格式的)

js 复制代码
db.User.find({name:"张三"})

相关文档:https://www.runoob.com/mongodb/mongodb-query.html

3、修改文档:(update)

只更新匹配到的第一条记录:

js 复制代码
//修改年龄为21岁的用户姓名
db.user.update({age:21},{$set:{name:'派蒙'}})

更新匹配到的所有记录:

js 复制代码
//加上{multi:true}表示修改多条
db.User.update({age:21},{$set:{age:99}},{multi:true})

相关文档:https://www.runoob.com/mongodb/mongodb-update.html

4、删除文档:(remove)

删除一个文档:

js 复制代码
db.user.remove(id)

删除所有文档:

js 复制代码
db.user.remove({})

相关文档:https://www.runoob.com/mongodb/mongodb-remove.html

3. SpringBoot操作MongoDB


spring-data是专门操作数据库的,而spring-data-mongodb是操作mongo的,它提供了两种操作mongo的方式:

  • 方式1:MongoTemplate
  • 方式2:MongoRepository

3.1 准备工作


1、创建SpringBoot项目,引入mongodb相关依赖:

xml 复制代码
<!--引入springboot工程并锁定版本-->
<parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>2.7.10</version>
  <relativePath/> <!-- lookup parent from repository -->
</parent>

<dependencies>
  <!--springbootweb的依赖-->
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  <!--lombok的依赖:简化实体开发-->
  <dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
  </dependency>
  <!--单元测试的依赖-->
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
  </dependency>
  <!--mongo的依赖-->
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb</artifactId>
  </dependency>
</dependencies>

<!--打包插件-->
<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-compiler-plugin</artifactId>
    </plugin>
  </plugins>
</build>

2、配置mongodb连接信息:

yml 复制代码
spring:
  data:
    mongodb:
      database: testdb
      host: 127.0.0.1
      port: 27017

logging:
  level:
    root: info

3、创建实体类:

java 复制代码
package cn.aopmin.domain;

import lombok.Data;
import org.springframework.data.mongodb.core.mapping.Document;
import java.util.Date;

/**
 * 用户实体类
 * @author 白豆五
 * @since 2024/7/19
 */
@Data
@Document("user") //指定表名
public class User {
    @Id
    private String id;
    
    private String name;
    private Integer age;
    private String email;
    private String password;
    private Date createTime;
}

3.2 编写测试


java 复制代码
import cn.aopmin.Launcher;
import cn.aopmin.domain.User;
import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.UpdateResult;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import java.util.Date;
import java.util.List;

/**
 * 使用MongoTemplate操作mongo
 *
 * @author 白豆五
 * @since 2024/7/19
 */
@SpringBootTest(classes = Launcher.class)
public class MongoTemplateTest {

    @Autowired
    private MongoTemplate mongoTemplate;

    // 添加
    @Test
    public void testInsert() {
        User user = User.builder()
                .name("test")
                .age(20)
                .createTime(new Date())
                .build();
        User obj = mongoTemplate.insert(user);
        assert obj != null;
        System.out.println("添加成功");

/*
NOTE:
insert() 和 save() 的区别:
    1. insert() 如果对象没有id, 则会自动生成id, 并插入数据库;
               如果对象有id, 则根据id更新对象
    2. save() 如果对象没有id, 则会自动生成id, 并插入数据库
              如果对象有id, 则会抛出异常
语法:
     db.user.insert({
        "name": "test",
        "age": "20",
        "createTime": ISODate("2024-07-19T09:09:09.000+08:00")
     });
 */
    }

    // 查询所有
    @Test
    public void testFindAll() {
        List<User> userList = mongoTemplate.findAll(User.class);
        userList.forEach(System.out::println);
    }

    // 根据id查
    @Test
    public void testFindById() {
        User user = mongoTemplate.findById("669a36442f07de177e4f92f5", User.class);
        System.out.println("user = " + user);
    }

    // 条件查询
    @Test
    public void testCondition() {
        // where name = 'test' and age = 20
        List<User> userList = mongoTemplate.find(
                // 查询条件,通过Criteria对象构建
                Query.query(Criteria.where("name").is("test").and("age").is(20)),
                // 查询结果类型
                User.class
        );
        System.out.println("userList = " + userList);
    }

    // 分页查询
    @Test
    public void testPage() {
        // 获取第1页, 每页2条数据
        List<User> userList =
                mongoTemplate.find(
                        // 查询条件
                        new Query()
                                .skip(0)  // 跳过前0条数据
                                .limit(2), // 取2条数据
                        // 查询结果类型
                        User.class
                );
        System.out.println("userList = " + userList);
    }


    // 删除
    @Test
    public void testDelete() {
        DeleteResult result = mongoTemplate.remove(
                Query.query(Criteria.where("_id").is("669a36442f07de177e4f92f5")),
                User.class
        );
        long count = result.getDeletedCount();
        System.out.println("count = " + count);
    }

    // 修改
    @Test
    public void testUpdate() {
        UpdateResult result = mongoTemplate.upsert(
                // 查询条件
                Query.query(Criteria.where("name").is("test")),
                // 修改内容
                Update.update("age", 21),
                // 修改结果类型
                User.class
        );
        // 影响行数
        long count = result.getMatchedCount();
        System.out.println("count = " + count);
    }
}

仓库地址:https://gitee.com/aopmin/mongo-demo

相关推荐
木卫二号Coding6 分钟前
docker-开源nocodb,使用已有数据库
数据库·docker·开源
StarRocks_labs17 分钟前
StarRocks 存算分离在得物的降本增效实践
数据库·数据仓库·湖仓
敲代码敲到头发茂密1 小时前
基于 LangChain 实现数据库问答机器人
数据库·人工智能·语言模型·langchain·机器人
一入程序无退路1 小时前
c语言传参数路径太长,导致无法获取参数
linux·c语言·数据库
陌夏微秋2 小时前
STM32单片机芯片与内部47 STM32 CAN内部架构 介绍
数据库·stm32·单片机·嵌入式硬件·架构·信息与通信
计算机学无涯3 小时前
Spring事务回滚
数据库·sql·spring
web130933203983 小时前
flume对kafka中数据的导入导出、datax对mysql数据库数据的抽取
数据库·kafka·flume
张声录13 小时前
【ETCD】【实操篇(二十)】浅谈etcd集群管理的艺术:从两阶段配置到灾难恢复的设计原则
数据库·etcd
qq_254674413 小时前
数据仓库和数据湖 数据仓库和数据库
数据库·数据仓库
--FGC--4 小时前
【第2篇】 Python与数据库基础
数据库·python·oracle