MongoDB快速实战与基本原理入门

一份面向开发者的 MongoDB 6.0 实战指南,涵盖核心概念、安装部署、CRUD 操作、数据类型详解及 Spring Boot 整合实践。


一、MongoDB 是什么?

MongoDB 是一款文档型数据库 ,使用 JSON/BSON 作为数据模型,由 C++ 编写,专为 Web 应用提供可扩展、高性能的数据存储方案。

它介于关系型数据库与非关系型数据库之间,是 NoSQL 阵营中功能最丰富、最像 RDBMS 的产品。其核心特点:

  • 半结构化:同一集合中的文档可以拥有不同字段,无需预先定义 Schema。

  • 弱关系 :没有外键约束,通过聚合管道($lookup)实现类似表连接的功能。

  • 强大的查询语言:支持索引、聚合、地理空间查询等,能完成大多数单表查询操作。

  • 原生高可用与水平扩展:通过复制集提供 99.999% 高可用,通过分片实现海量数据无缝扩容。

截至 2021 年底,MongoDB 在数据库总排名第 5,NoSQL 中排名第 1,社区活跃度和应用广度持续攀升。


二、MongoDB vs 关系型数据库(概念对照)

MongoDB 概念 关系型数据库概念
数据库(Database) 数据库
集合(Collection) 表(Table)
文档(Document) 行(Row)
字段(Field) 列(Column)
索引(Index) 索引
_id 主键(Primary Key)
视图(View) 视图
$lookup 表连接(Join)

注意:MongoDB 的文档支持嵌套数组,更贴合面向对象的编程模型,开发效率更高。


三、适用场景

只要满足以下任意一项,就可以考虑使用 MongoDB:

  • 游戏:用户信息、装备、积分以内嵌文档存储,方便查询更新。

  • 物流:订单状态变更以数组存储,一次查询获取完整轨迹。

  • 社交:用户信息、朋友圈,配合地理位置索引实现"附近的人"。

  • 物联网:设备信息、日志存储,并进行多维分析。

  • 视频直播:用户、礼物等实时数据。

  • 大数据:作为云存储系统,方便数据提取分析。

国内外众多互联网公司(如阿里、腾讯、Google、Facebook 等)都在生产环境中广泛使用 MongoDB。


四、Linux 环境搭建(CentOS 7)

1. 下载并解压 MongoDB Community Server

bash

复制代码
wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-6.0.5.tgz
tar -zxvf mongodb-linux-x86_64-rhel70-6.0.5.tgz

2. 创建数据目录和日志文件

bash

复制代码
mkdir -p /mongodb/data /mongodb/log
touch /mongodb/log/mongodb.log

3. 启动 MongoDB(命令行方式)

bash

复制代码
bin/mongod --port=27017 --dbpath=/mongodb/data --logpath=/mongodb/log/mongodb.log --bind_ip=0.0.0.0 --fork

4. 使用配置文件启动(推荐)

创建 /mongodb/conf/mongo.conf

yaml

复制代码
systemLog:
  destination: file
  path: /mongodb/log/mongod.log
  logAppend: true
storage:
  dbPath: /mongodb/data
  engine: wiredTiger
  journal:
    enabled: true
net:
  bindIp: 0.0.0.0
  port: 27017
processManagement:
  fork: true

启动:

bash

复制代码
mongod -f /mongodb/conf/mongo.conf

5. 关闭 MongoDB

bash

复制代码
# 方式一
mongod --port=27017 --dbpath=/mongodb/data --shutdown

# 方式二(进入 mongosh)
use admin
db.shutdownServer()

6. 安装 mongosh(MongoDB 6.0 已移除旧的 mongo 客户端)

bash

复制代码
wget https://downloads.mongodb.com/compass/mongodb-mongosh-1.8.0.x86_64.rpm
yum install -y mongodb-mongosh-1.8.0.x86_64.rpm

连接:

bash

复制代码
mongosh --host=192.168.65.206 --port=27017

五、安全认证(用户管理)

1. 创建管理员用户(在 admin 库中)

javascript

复制代码
use admin
db.createUser({user: "fox", pwd: "fox", roles: ["root"]})

2. 创建应用数据库用户

javascript

复制代码
use appdb
db.createUser({user: "appdb", pwd: "fox", roles: ["dbOwner"]})

3. 启用认证启动

bash

复制代码
mongod -f /mongodb/conf/mongo.conf --auth

4. 连接时认证

bash

复制代码
mongosh 192.168.65.206:27017 -u fox -p fox --authenticationDatabase=admin

六、Docker 安装(快速体验)

bash

复制代码
docker pull mongo:6.0.5
docker run --name mongo-server -p 29017:27017 \
  -e MONGO_INITDB_ROOT_USERNAME=fox \
  -e MONGO_INITDB_ROOT_PASSWORD=fox \
  -d mongo:6.0.5 --wiredTigerCacheSizeGB 1

连接:

bash

复制代码
mongosh ip:29017 -u fox -p fox

七、核心文档操作(CRUD)

1. 插入文档

javascript

复制代码
// 插入单个
db.books.insertOne({ title: "MongoDB实战", type: "technology", favCount: 30 })

// 批量插入(可用 load("books.js") 执行脚本)
db.books.insertMany([...])

2. 查询文档

javascript

复制代码
// 查询所有
db.books.find()

// 条件查询(收藏数 > 60)
db.books.find({ type: "travel", favCount: { $gt: 60 } })

// 正则匹配
db.books.find({ type: { $regex: "so" } })

// 排序 + 分页
db.books.find().sort({ favCount: -1 }).skip(16).limit(8)

// 巧分页(避免 skip 大数据量)
db.books.find({ _id: { $gt: lastId } }).sort({ _id: 1 }).limit(10)

3. 更新文档

javascript

复制代码
// 更新单个(自增收藏数)
db.books.updateOne({ _id: ObjectId("...") }, { $inc: { favCount: 1 } })

// 更新多个(添加发布时间)
db.books.updateMany({ type: "novel" }, { $set: { publishedDate: new Date() } })

// upsert(不存在则插入)
db.books.updateOne(
  { title: "my book" },
  { $set: { tags: ["nosql"], type: "none" } },
  { upsert: true }
)

4. 删除文档

javascript

复制代码
db.books.deleteOne({ type: "novel" })
db.books.deleteMany({ type: "novel" })
db.books.findOneAndDelete({ type: "novel" })  // 返回被删文档

5. 批量操作(bulkWrite)

javascript

复制代码
db.pizzas.bulkWrite([
  { insertOne: { document: { _id: 3, type: "beef", price: 6 } } },
  { updateOne: { filter: { type: "cheese" }, update: { $set: { price: 8 } } } },
  { deleteOne: { filter: { type: "pepperoni" } } }
])

八、BSON 数据类型与 ObjectId

为什么使用 BSON?

  • 二进制编码,遍历更快(记录每个元素长度,支持 seek 直接读取)。

  • 支持更丰富的类型:日期、二进制、ObjectId、Decimal128 等。

  • 文档最大 16MB,嵌套级别不超过 100。

ObjectId 结构(12 字节)

  • 4 字节:Unix 时间戳(秒)

  • 5 字节:随机数(机器号 + 进程号)

  • 3 字节:计数器(初始随机)

自动生成,保证唯一性,减轻服务器压力。

日期类型

MongoDB 使用 UTC 时间存储,new Date()ISODate() 均生成 ISODate 类型。


九、内嵌文档与数组(灵活建模)

内嵌文档示例

javascript

复制代码
db.books.insert({
  title: "撒哈拉的故事",
  author: { name: "三毛", gender: "女", hometown: "重庆" }
})

// 查询
db.books.find({ "author.name": "三毛" })

// 更新内嵌字段
db.books.updateOne({ "author.name": "三毛" }, { $set: { "author.hometown": "重庆/台湾" } })

数组操作

javascript

复制代码
// 添加标签
db.books.updateOne({ "author.name": "三毛" }, { $push: { tags: "猎奇" } })

// 批量添加并保留最后 3 个
db.books.updateOne(
  { "author.name": "三毛" },
  { $push: { tags: { $each: ["伤感", "想象力"], $slice: -3 } } }
)

// 根据数组元素查询
db.books.find({ tags: "伤感" })
db.books.find({ tags: { $all: ["伤感", "想象力"] } })

多属性商品(数组内嵌文档)

javascript

复制代码
db.goods.insertMany([{
  name: "羽绒服",
  tags: [
    { tagKey: "size", tagValue: ["M","L","XL"] },
    { tagKey: "color", tagValue: ["黑色","宝蓝"] }
  ]
}])

// 查询 color=黑色 且 size=XL
db.goods.find({
  tags: {
    $all: [
      { $elemMatch: { tagKey: "color", tagValue: "黑色" } },
      { $elemMatch: { tagKey: "size", tagValue: "XL" } }
    ]
  }
})

十、固定集合(Capped Collection)

固定集合是限定大小的集合,采用 FIFO(先进先出)策略,适用于日志消息队列最新 TopN 等场景。

javascript

复制代码
// 创建(size=4096字节,max=10条)
db.createCollection("logs", { capped: true, size: 4096, max: 10 })

// 普通集合转固定集合
db.runCommand({ convertToCapped: "mycoll", size: 100000 })

实战:股票消息队列

生产者每秒插入一条股价变动:

javascript

复制代码
function pushEvent() {
  while (true) {
    db.stock_queue.insert({
      timestamped: new Date(),
      stock: "MongoDB Inc",
      price: 100 * Math.random()
    });
    sleep(1000);
  }
}

消费者持续监听(类似 tail -f):

javascript

复制代码
function listen() {
  var cursor = db.stock_queue.find({ timestamped: { $gte: new Date() } }).tailable();
  while (true) {
    if (cursor.hasNext()) {
      print(JSON.stringify(cursor.next(), null, 2));
    }
    sleep(1000);
  }
}

十一、Spring Boot 整合 MongoDB

1. 引入依赖

xml

复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

2. 配置 yml

yaml

复制代码
spring:
  data:
    mongodb:
      uri: mongodb://fox:fox@192.168.65.174:27017/test?authSource=admin

3. 实体类(使用注解)

java

复制代码
@Document("emp")
@Data
public class Employee {
    @Id
    private Integer id;
    @Field("username")
    private String name;
    @Field
    private int age;
    @Field
    private Double salary;
    @Field
    private Date entryDay;
}

4. 常用操作示例

插入

java

复制代码
mongoTemplate.insert(employee);
mongoTemplate.insert(list, Employee.class);

查询

java

复制代码
// 条件 + 排序 + 分页
Query query = new Query(Criteria.where("salary").gt(4000).lt(10000))
    .with(Sort.by(Sort.Order.desc("salary")))
    .skip(0).limit(4);
List<Employee> list = mongoTemplate.find(query, Employee.class);

更新

java

复制代码
Query query = new Query(Criteria.where("salary").is(15000));
Update update = new Update().set("salary", 13000);
UpdateResult result = mongoTemplate.updateMulti(query, update, Employee.class);

删除

java

复制代码
Query query = new Query(Criteria.where("salary").is(10000));
mongoTemplate.remove(query, Employee.class);

5. 去掉自动添加的 _class 字段(可选)

java

复制代码
@Configuration
public class MongoConfig {
    @Bean
    public MappingMongoConverter mappingMongoConverter(
            MongoDatabaseFactory factory, MongoMappingContext context, MongoCustomConversions conversions) {
        DbRefResolver resolver = new DefaultDbRefResolver(factory);
        MappingMongoConverter converter = new MappingMongoConverter(resolver, context);
        converter.setCustomConversions(conversions);
        converter.setTypeMapper(new DefaultMongoTypeMapper(null)); // 关键
        return converter;
    }
}

十二、小结

MongoDB 以其灵活的文档模型强大的查询能力原生高可用与扩展性,成为 NoSQL 领域的领军者。无论是快速迭代的互联网产品,还是海量数据的物联网、大数据场景,MongoDB 都能显著降低开发成本,提升系统弹性。

本文从概念到实战,从 Linux 安装到 Spring Boot 整合,覆盖了日常开发所需的全部基础知识。希望你能以此为起点,在项目中充分发挥 MongoDB 的优势。

相关推荐
KASH_SHADOW1 小时前
8-Mysql的安装与配置
数据库·mysql·adb
澈2071 小时前
【无标题】QT入门第十二天:数据库编程(下)模型视图与数据展示 | 零基础学QT
数据库·qt·oracle
云絮.2 小时前
数据库事务
java·开发语言·数据库
Leon-Ning Liu3 小时前
【真实经验分享】OGG抽取进程报错 ORA-07445 [kgherrordmp()+986] ORA-00600 [17114]分析步骤
运维·数据库
CCPC不拿奖不改名3 小时前
Redis 工程化部署深度解析
linux·服务器·数据库·redis·深度学习·缓存·rag
吴声子夜歌3 小时前
SQL进阶——自连接
数据库·sql
云贝教育-郑老师3 小时前
TDSQL(MySQL版)分布式事务实现机制深度解析:从两阶段提交到全局一致性读
数据库·sql
gb448oww53 小时前
Redis分布式锁进阶第三十五篇
数据库·redis·分布式