
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增Insertdb.users.insertOne({name:张三,age:20,tags:[java,mysql]})db.users.insertMany([{name:李四,age:22},{name:王五,age:25}])不指定_id时MongoDB 自动生成全局唯一的ObjectId。查Finddb.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字段是否存在改Updatedb.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等更新运算符否则会用新文档整体替换原文档其他字段全部丢失。删Deletedb.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 关联查询类似 JOINdb.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推荐 --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-mongodb/artifactId/dependencyspring:data:mongodb:uri:mongodb://localhost:27017/test二方式一MongoTemplate灵活适合复杂查询AutowiredprivateMongoTemplatemongoTemplate;// 增mongoTemplate.save(user);// 有 _id 则更新无则新增mongoTemplate.insert(user);// 强制新增// 查支持动态条件、分页、排序QueryquerynewQuery(Criteria.where(age).gte(20));query.with(Sort.by(Sort.Direction.DESC,age)).skip(0).limit(10);ListUserlistmongoTemplate.find(query,User.class);// 改UpdateupdatenewUpdate().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);// 聚合AggregationaggAggregation.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 映射主键DataDocument(collectionusers)publicclassUser{IdprivateStringid;privateStringname;privateIntegerage;}// 2. 接口继承 MongoRepository 即拥有基础 CRUD方法名可自动推导查询publicinterfaceUserRepositoryextendsMongoRepositoryUser,String{ListUserfindByName(Stringname);// 等价 find({name: xxx})Query({ age: { $gte: ?0 } })// 或用注解自定义ListUserfindByAgeGte(Integerage);}// 3. 调用userRepository.save(user);userRepository.findById(id);userRepository.deleteById(id);方式适用场景MongoTemplate复杂查询、聚合、动态条件MongoRepository简单标准 CRUD开发效率高五、高可用部署单机 MongoDB 存在容量与单点故障的瓶颈生产环境通过副本集与分片集群解决。一副本集Replica Set一组维护相同数据的节点集群解决高可用 数据冗余。角色说明Primary唯一可读写的节点写操作都走它Secondary从主节点同步数据默认只读可分担读请求Arbiter不存数据只参与投票选举客户端 ──写──→ Primary ──oplog复制──→ Secondary / Secondaryoplog主节点记录写操作从节点拉取重放以保持数据一致故障转移主节点宕机后剩余节点自动选举出新主默认几秒标准架构为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重点连接串要带replicaSetrs0和多个节点地址才能在主节点切换时自动重连写仍集中在单 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:app123456localhost:27017/test?authSourcetest其他安全措施bindIp限制内网访问禁止暴露公网、开启 TLS 传输加密、WiredTiger 存储加密、业务账号遵循最小权限。小结模块一句话理解基础操作增insert、删delete、改update必须带$set、查find聚合aggregate管道$match过滤 →$group分组 →$sort排序索引加快读、拖慢写复合索引遵循最左前缀Java 操作灵活用MongoTemplate简单用MongoRepository副本集多副本 自动故障转移解决高可用分片集群Mongos 路由 Config 元数据 多 Shard解决海量数据安全认证建用户 → 开--auth→ 连接带authSource遵循最小权限