一文吃透 MongoDB,文档型数据库 CRUD 全解
一、MongoDB 简介
MongoDB 是一个文档型 NoSQL 数据库,使用 BSON(二进制 JSON) 格式存储数据。
核心特点
| 特点 | 说明 |
|---|---|
| 文档存储 | 数据以 JSON/BSON 文档形式存储 |
| 无 Schema | 同一集合中的文档可以有不同的字段 |
| 高性能 | 支持索引、聚合、分片 |
| 高可用 | 副本集提供自动故障转移 |
| 水平扩展 | 分片集群支持海量数据 |
与 MySQL 对比
| MySQL | MongoDB |
|---|---|
| 数据库 (Database) | 数据库 (Database) |
| 表 (Table) | 集合 (Collection) |
| 行 (Row) | 文档 (Document) |
| 列 (Column) | 字段 (Field) |
| 主键 (Primary Key) | _id (ObjectId) |
| JOIN | 聚合管道 ($lookup) |
二、安装与启动
2.1 Docker 安装
# 拉取镜像docker pull mongo:7.0# 启动容器docker run -d --name mongodb -p 27017:27017 mongo:7.0# 进入容器docker exec -it mongodb mongosh
2.2 连接 MongoDB
# 本地连接mongosh# 指定主机端口mongosh --host localhost --port 27017# 带认证mongosh "mongodb://admin:password@localhost:27017"# 指定数据库mongosh mydb
三、数据库与集合操作
3.1 数据库操作
// 查看所有数据库show dbs// 切换/创建数据库(不存在则创建)use mydb// 查看当前数据库db// 删除当前数据库db.dropDatabase()// 查看数据库统计信息db.stats()
3.2 集合操作
// 创建集合(显式创建)db.createCollection("users")// 查看所有集合show collections// 删除集合db.users.drop()// 查看集合统计db.users.stats()
四、CRUD 操作
4.1 插入文档
// 插入单个文档db.users.insertOne({name: "张三",age: 25,email: "zhangsan@example.com",city: "北京",hobbies: ["阅读", "游泳"]})// 插入多个文档db.users.insertMany([{ name: "李四", age: 30, city: "上海" },{ name: "王五", age: 22, city: "广州" },{ name: "赵六", age: 28, city: "深圳" }])// 插入返回的 _id// 返回结果会包含插入的 _id
4.2 查询文档
// ============ 基础查询 ============// 查询所有db.users.find()// 查询所有(格式化输出)db.users.find().pretty()// 查询指定条件db.users.find({ name: "张三" })// 查询指定字段(1=显示,0=不显示)db.users.find({ name: "张三" },{ name: 1, age: 1, _id: 0 })// 查询第一条db.users.findOne({ name: "张三" })// ============ 比较运算符 ============// 等于db.users.find({ age: 25 })// 不等于db.users.find({ age: { $ne: 25 } })// 大于db.users.find({ age: { $gt: 25 } })// 大于等于db.users.find({ age: { $gte: 25 } })// 小于db.users.find({ age: { $lt: 25 } })// 小于等于db.users.find({ age: { $lte: 25 } })// 在范围内db.users.find({ age: { $in: [25, 30, 35] } })// 不在范围内db.users.find({ age: { $nin: [25, 30, 35] } })// ============ 逻辑运算符 ============// AND(默认)db.users.find({ name: "张三", age: 25 })// ORdb.users.find({$or: [{ name: "张三" },{ age: 25 }]})// NOTdb.users.find({ age: { $not: { $gt: 30 } } })// NOR(所有条件都不满足)db.users.find({$nor: [{ age: 25 },{ city: "北京" }]})// ============ 数组查询 ============// 包含某个元素db.users.find({ hobbies: "阅读" })// 包含所有指定元素db.users.find({ hobbies: { $all: ["阅读", "游泳"] } })// 数组长度db.users.find({ hobbies: { $size: 2 } })// ============ 正则查询 ============// 以"张"开头db.users.find({ name: /^张/ })// 包含"三"db.users.find({ name: /三/ })// 不区分大小写db.users.find({ name: { $regex: "zhang", $options: "i" } })// ============ 分页排序 ============// 排序(1=升序,-1=降序)db.users.find().sort({ age: 1 })// 跳过(分页)db.users.find().skip(10).limit(5)// 计数db.users.find().count()db.users.countDocuments({ age: { $gt: 25 } })
4.3 更新文档
// ============ $set(设置字段) ============// 更新单个文档db.users.updateOne({ name: "张三" },{ $set: { age: 26, city: "北京" } })// 更新多个文档db.users.updateMany({ city: "北京" },{ $set: { city: "北京市" } })// 替换整个文档(除 _id 外)db.users.replaceOne({ name: "张三" },{ name: "张三", age: 26, city: "北京" })// 如果不存在则插入(upsert)db.users.updateOne({ name: "张三" },{ $set: { age: 26 } },{ upsert: true })// ============ $inc(自增) ============// 年龄 +1db.users.updateOne({ name: "张三" },{ $inc: { age: 1 } })// 年龄 -1db.users.updateOne({ name: "张三" },{ $inc: { age: -1 } })// ============ $unset(删除字段) ============db.users.updateOne({ name: "张三" },{ $unset: { city: "" } })// ============ $rename(重命名字段) ============db.users.updateOne({ name: "张三" },{ $rename: { city: "address" } })// ============ 数组操作 ============// 添加元素到数组db.users.updateOne({ name: "张三" },{ $push: { hobbies: "跑步" } })// 添加多个元素db.users.updateOne({ name: "张三" },{ $push: { hobbies: { $each: ["跑步", "骑行"] } } })// 删除数组元素db.users.updateOne({ name: "张三" },{ $pull: { hobbies: "跑步" } })// 删除所有匹配的元素db.users.updateOne({ name: "张三" },{ $pullAll: { hobbies: ["跑步", "骑行"] } })// 添加元素到数组(去重)db.users.updateOne({ name: "张三" },{ $addToSet: { hobbies: "阅读" } })// 删除第一个/最后一个元素db.users.updateOne({ name: "张三" },{ $pop: { hobbies: 1 } } // 1=最后一个,-1=第一个)
4.4 删除文档
// 删除单个文档db.users.deleteOne({ name: "张三" })// 删除多个文档db.users.deleteMany({ age: { $lt: 18 } })// 删除所有文档db.users.deleteMany({})
五、聚合管道
5.1 基础聚合
// ============ $match(过滤) ============db.orders.aggregate([{ $match: { status: "completed" } }])// ============ $group(分组) ============// 按城市分组统计db.users.aggregate([{$group: {_id: "$city",count: { $sum: 1 },avgAge: { $avg: "$age" },maxAge: { $max: "$age" },minAge: { $min: "$age" }}}])// ============ $sort(排序) ============db.users.aggregate([{ $sort: { age: -1 } }])// ============ $limit / $skip(分页) ============db.users.aggregate([{ $skip: 10 },{ $limit: 5 }])// ============ $project(投影) ============db.users.aggregate([{$project: {name: 1,age: 1,isAdult: { $gte: ["$age", 18] },fullName: { $concat: ["$firstName", " ", "$lastName"] }}}])// ============ $lookup(关联查询) ============db.orders.aggregate([{$lookup: {from: "users",localField: "userId",foreignField: "_id",as: "userInfo"}}])// ============ $unwind(展开数组) ============db.users.aggregate([{ $unwind: "$hobbies" },{ $group: { _id: "$hobbies", count: { $sum: 1 } } }])
5.2 综合示例
// 统计每个城市用户的平均年龄,按平均年龄排序db.users.aggregate([{ $match: { age: { $gt: 0 } } },{ $group: { _id: "$city", avgAge: { $avg: "$age" }, count: { $sum: 1 } } },{ $sort: { avgAge: -1 } },{ $limit: 10 }])
六、索引
6.1 索引操作
// 查看索引db.users.getIndexes()// 创建单字段索引db.users.createIndex({ age: 1 }) // 升序db.users.createIndex({ age: -1 }) // 降序// 创建唯一索引db.users.createIndex({ email: 1 }, { unique: true })// 创建复合索引db.users.createIndex({ city: 1, age: -1 })// 创建文本索引(全文搜索)db.users.createIndex({ name: "text", description: "text" })// 创建 TTL 索引(自动过期)db.users.createIndex({ createdAt: 1 }, { expireAfterSeconds: 3600 })// 删除索引db.users.dropIndex("age_1")// 删除所有索引(除 _id 外)db.users.dropIndexes()// 查看索引大小db.users.totalIndexSize()
七、Java 集成
7.1 引入依赖
<dependency><groupId>org.mongodb</groupId><artifactId>mongodb-driver-sync</artifactId><version>4.11.0</version></dependency>
7.2 基本操作
import com.mongodb.client.*;import org.bson.Document;public class MongoDBDemo {public static void main(String[] args) {// 1. 连接 MongoDBMongoClient client = MongoClients.create("mongodb://localhost:27017");MongoDatabase db = client.getDatabase("mydb");MongoCollection<Document> collection = db.getCollection("users");// 2. 插入Document doc = new Document("name", "张三").append("age", 25).append("city", "北京");collection.insertOne(doc);// 3. 查询Document query = new Document("name", "张三");FindIterable<Document> results = collection.find(query);for (Document d : results) {System.out.println(d.toJson());}// 4. 更新Document update = new Document("$set", new Document("age", 26));collection.updateOne(query, update);// 5. 删除collection.deleteOne(query);// 6. 关闭连接client.close();}}
7.3 Spring Boot 集成
# application.ymlspring:data:mongodb:uri: mongodb://localhost:27017/mydb# 或host: localhostport: 27017database: mydb
@Servicepublic class UserService {@Autowiredprivate MongoTemplate mongoTemplate;public User save(User user) {return mongoTemplate.save(user);}public List<User> findAll() {return mongoTemplate.findAll(User.class);}public User findById(String id) {return mongoTemplate.findById(id, User.class);}public List<User> findByAge(int age) {Query query = new Query(Criteria.where("age").gte(age));return mongoTemplate.find(query, User.class);}publicvoiddeleteById(String id) {Query query = new Query(Criteria.where("id").is(id));mongoTemplate.remove(query, User.class);}}
八、常用命令速查表
| 命令 | 说明 |
|---|---|
show dbs |
查看所有数据库 |
use dbname |
切换数据库 |
show collections |
查看所有集合 |
db.collection.find() |
查询数据 |
db.collection.findOne() |
查询一条 |
db.collection.insertOne() |
插入一条 |
db.collection.insertMany() |
插入多条 |
db.collection.updateOne() |
更新一条 |
db.collection.updateMany() |
更新多条 |
db.collection.deleteOne() |
删除一条 |
db.collection.deleteMany() |
删除多条 |
db.collection.countDocuments() |
计数 |
db.collection.createIndex() |
创建索引 |
db.collection.getIndexes() |
查看索引 |
db.collection.drop() |
删除集合 |
db.dropDatabase() |
删除数据库 |
END
点击
上方文字
关注我们
夜雨聆风