☰
MongoDB基础知识
2026/10/3 12:47:54 网站建设 项目流程

MongoDB简介

MongoDB 是面向文档的 NoSQL 数据库,数据以BSON(类 JSON 的二进制格式)文档存储,无需预定义表结构。

与 MySQL 概念对照:

MySQLMongoDB说明
databasedatabase数据库
tablecollection集合,无固定结构
rowdocument文档
columnfield字段
primary key_id主键,自动生成ObjectId

核心特点:文档模型字段灵活、内嵌文档减少关联查询、天生支持分片水平扩展。


一、基础操作

(一)库与集合

show dbs// 查看所有数据库use test// 创建/切换数据库db// 查看当前数据库db.dropDatabase()// 删除当前数据库show collections// 查看集合db.users.drop()// 删除集合

重点:use不存在的库不会立即创建,插入数据后才真正落库;集合也无需显式创建,插入文档时自动创建。

(二)增删改查(CRUD)

增(Insert):

db.users.insertOne({name:"张三",age:20,tags:["java","mysql"]})db.users.insertMany([{name:"李四",age:22},{name:"王五",age:25}])

不指定_id时,MongoDB 自动生成全局唯一的ObjectId。

查(Find):

db.users.find()// 查询全部db.users.findOne({name:"张三"})// 查询一条db.users.find({age:{$gte:20}})// 比较运算db.users.find({$or:[{age:20},{age:25}]})// 逻辑运算db.users.find({tags:"java"})// 数组字段包含db.users.find({name:/张/})// 模糊查询(正则)db.users.find({age:{$gt:20}},{name:1,age:1,_id:0})// 投影:1 显示 / 0 隐藏db.users.find().sort({age:1})// 排序:1 升序,-1 降序db.users.find().skip(1).limit(2)// 分页

常用查询运算符:

运算符含义运算符含义
$gt/$gte大于 / 大于等于$in/$nin在 / 不在集合内
$lt/$lte小于 / 小于等于$and/$or逻辑与 / 或
$ne不等于$exists字段是否存在

改(Update):

db.users.updateOne({name:"张三"},{$set:{age:21,city:"北京"}})// 修改字段db.users.updateMany({age:{$lt:20}},{$set:{status:"未成年"}})// 批量修改db.users.updateOne({name:"张三"},{$inc:{age:1}})// 自增db.users.updateOne({name:"张三"},{$unset:{city:""}})// 删除字段db.users.updateOne({name:"张三"},{$push:{tags:"redis"}})// 数组追加db.users.updateOne({name:"张三"},{$pull:{tags:"mysql"}})// 数组移除

易错点:更新必须配合$set等更新运算符,否则会用新文档整体替换原文档,其他字段全部丢失。

删(Delete):

db.users.deleteOne({name:"张三"})// 删除单条db.users.deleteMany({age:{$lt:18}})// 删除多条db.users.deleteMany({})// 清空集合

二、聚合操作(Aggregation)

聚合用于对文档分组、统计、计算,以管道pipeline形式执行,文档依次流经各阶段,等价于 SQL 的GROUP BY+ 函数。

常用管道阶段:

阶段作用类比 SQL阶段作用类比 SQL
$match过滤文档WHERE$limit/$skip限制/跳过LIMIT
$group分组计算GROUP BY$unwind拆解数组—
$sort排序ORDER BY$lookup关联集合JOIN
$project指定输出字段SELECT———

常用累加器($group内):$sum求和、$avg平均、$max/$min最大最小、$push/$addToSet收集数组。

// 分组统计 + 排序db.users.aggregate([{$group:{_id:"$age",count:{$sum:1}}},{$sort:{count:-1}}])// 过滤后整体统计db.users.aggregate([{$match:{age:{$gte:20}}},{$group:{_id:null,avgAge:{$avg:"$age"}}}])// $unwind 拆数组,统计每个 tag 出现次数db.users.aggregate([{$unwind:"$tags"},{$group:{_id:"$tags",count:{$sum:1}}}])// $lookup 关联查询(类似 JOIN)db.orders.aggregate([{$lookup:{from:"users",localField:"userId",foreignField:"_id",as:"userInfo"}}])

重点:$group的_id是分组依据,写null表示整体统计;字段引用必须加$前缀;$match应放管道最前,可提前缩小数据量。


三、索引(Index)

索引给字段建立有序结构,加速查询,避免全集合扫描(COLLSCAN)。

索引类型:

类型说明
单字段 / 复合索引单字段 / 多字段组合,复合索引遵循最左前缀
唯一索引字段值不能重复
文本索引支持全文检索
TTL 索引文档到期自动删除
地理空间索引2dsphere,支持位置查询
db.users.createIndex({name:1})// 单字段(1 升序 / -1 降序)db.users.createIndex({age:1,name:-1})// 复合索引db.users.createIndex({email:1},{unique:true})// 唯一索引db.logs.createIndex({createTime:1},{expireAfterSeconds:3600})// TTL 索引(3600 秒后过期)db.users.getIndexes()// 查看索引db.users.dropIndex({name:1})// 删除索引

执行计划(性能分析):

db.users.find({name:"张三"}).explain("executionStats")// stage: "COLLSCAN" → 全表扫描(慢) stage: "IXSCAN" → 索引扫描(快)

重点:索引加快读、拖慢写,不宜滥用;复合索引{a:1,b:1}支持按a或a,b查,不支持只按b查。


四、Java 操作 MongoDB

(一)依赖与配置

<!-- Spring Boot 官方 starter(推荐) --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId></dependency>
spring:data:mongodb:uri:mongodb://localhost:27017/test

(二)方式一:MongoTemplate(灵活,适合复杂查询)

@AutowiredprivateMongoTemplatemongoTemplate;// 增mongoTemplate.save(user);// 有 _id 则更新,无则新增mongoTemplate.insert(user);// 强制新增// 查(支持动态条件、分页、排序)Queryquery=newQuery(Criteria.where("age").gte(20));query.with(Sort.by(Sort.Direction.DESC,"age")).skip(0).limit(10);List<User>list=mongoTemplate.find(query,User.class);// 改Updateupdate=newUpdate().set("age",21).inc("score",1);mongoTemplate.updateFirst(Query.query(Criteria.where("name").is("张三")),update,User.class);// 删mongoTemplate.remove(Query.query(Criteria.where("name").is("张三")),User.class);// 聚合Aggregationagg=Aggregation.newAggregation(Aggregation.match(Criteria.where("age").gte(20)),Aggregation.group("age").count().as("count"),Aggregation.sort(Sort.Direction.DESC,"count"));mongoTemplate.aggregate(agg,"users",Document.class);

(三)方式二:MongoRepository(简单 CRUD)

// 1. 实体类:@Document 指定集合,@Id 映射主键@Data@Document(collection="users")publicclassUser{@IdprivateStringid;privateStringname;privateIntegerage;}// 2. 接口继承 MongoRepository 即拥有基础 CRUD,方法名可自动推导查询publicinterfaceUserRepositoryextendsMongoRepository<User,String>{List<User>findByName(Stringname);// 等价 find({name: "xxx"})@Query("{ 'age': { $gte: ?0 } }")// 或用注解自定义List<User>findByAgeGte(Integerage);}// 3. 调用userRepository.save(user);userRepository.findById(id);userRepository.deleteById(id);
方式适用场景
MongoTemplate复杂查询、聚合、动态条件
MongoRepository简单标准 CRUD,开发效率高

五、高可用部署

单机 MongoDB 存在容量与单点故障的瓶颈,生产环境通过副本集与分片集群解决。

(一)副本集(Replica Set)

一组维护相同数据的节点集群,解决高可用 + 数据冗余。

角色说明
Primary唯一可读写的节点,写操作都走它
Secondary从主节点同步数据,默认只读,可分担读请求
Arbiter不存数据,只参与投票选举
客户端 ──写──→ Primary ──oplog复制──→ Secondary / Secondary
  • oplog:主节点记录写操作,从节点拉取重放以保持数据一致
  • 故障转移:主节点宕机后,剩余节点自动选举出新主(默认几秒)
  • 标准架构为1 Primary + 2 Secondary(三节点),保证挂一台仍能选举
// 启动节点(--replSet 指定副本集名)后初始化rs.initiate({_id:"rs0",members:[{_id:0,host:"localhost:27017"},{_id:1,host:"localhost:27018"},{_id:2,host:"localhost:27019"}]})rs.status()// 查看状态,重点看 stateStr 是否为 PRIMARY

重点:连接串要带replicaSet=rs0和多个节点地址,才能在主节点切换时自动重连;写仍集中在单 Primary,无法水平扩展写能力。

(二)分片集群(Sharded Cluster)

把数据分散到多个分片,解决单机存储容量与写入吞吐瓶颈,用于海量数据。

组件作用
Shard(分片)实际存储数据,每个分片本身是一个副本集
Config Server存储集群元数据(分片规则、数据分布)
Mongos客户端统一入口,路由请求到对应分片,对客户端透明
客户端 ──→ Mongos ──→ Config Server(元数据) │ ┌──────┼──────┐ Shard1 Shard2 Shard3 (均为副本集)

分片键(Shard Key):决定数据如何分布,是分片集群的核心设计点。

策略特点
范围分片范围查询高效,但易数据倾斜(热点)
哈希分片分布均匀,但范围查询需广播
sh.enableSharding("test")// 开启数据库分片sh.shardCollection("test.users",{userId:"hashed"})// 按哈希分片键分片sh.status()// 查看分片状态

重点:分片键选择至关重要——基数低、单调递增(如时间戳)的字段易造成热点,建议用哈希分片或复合分片键。


六、安全认证

MongoDB 默认不开启认证,生产环境必须开启。

概念说明
认证 Authentication验证"你是谁"(账号密码)
授权 Authorization验证"你能做什么"(角色权限)

常用内置角色:read只读、readWrite读写、dbAdmin库管理、userAdmin用户管理、root超级管理员。

开启认证步骤:

// 1. 先以无认证方式启动,创建管理员用户use admin db.createUser({user:"admin",pwd:"123456",roles:[{role:"root",db:"admin"}]})// 2. 创建业务库普通用户use test db.createUser({user:"appUser",pwd:"app123456",roles:[{role:"readWrite",db:"test"}]})
# 3. 重启并开启认证mongod--auth--dbpath/data/db# 或配置文件 security.authorization: enabled
# 4. 连接串:authSource 表示认证库mongodb://appUser:app123456@localhost:27017/test?authSource=test

其他安全措施:bindIp限制内网访问(禁止暴露公网)、开启 TLS 传输加密、WiredTiger 存储加密、业务账号遵循最小权限。


小结

模块一句话理解
基础操作增insert、删delete、改update(必须带$set)、查find
聚合aggregate管道:$match过滤 →$group分组 →$sort排序
索引加快读、拖慢写;复合索引遵循最左前缀
Java 操作灵活用MongoTemplate,简单用MongoRepository
副本集多副本 + 自动故障转移,解决高可用
分片集群Mongos 路由 + Config 元数据 + 多 Shard,解决海量数据
安全认证建用户 → 开--auth→ 连接带authSource,遵循最小权限

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询