MongoDB 的增刪改查(CRUD)操作是其核心功能,主要通過 mongo shell
或驅動(如 Node.js、Python 等)實現。以下是最常用操作的詳細說明及示例(基于 mongo shell
語法)。
?一、插入操作(Insert)??
用于向集合中添加文檔,支持插入單條或多條數據。
?**1. 插入單條文檔:insertOne()
**?
向集合中插入一個文檔,返回操作結果(包含是否成功、插入的 _id
等信息)。
?語法?:
db.collection.insertOne({<field1>: <value1>,<field2>: <value2>,...
})
?示例?:
向 users
集合插入一條用戶記錄:
// 若集合不存在,MongoDB 會自動創建
db.users.insertOne({name: "Alice",age: 25,email: "alice@example.com",hobbies: ["reading", "hiking"],isStudent: false
})
?輸出結果?:
{"acknowledged": true, // 操作是否被服務端確認(默認開啟寫確認)"insertedId": ObjectId("650a8b9d0f7d0e1a2c3b4d5e") // 自動生成的唯一 _id
}
?**2. 插入多條文檔:insertMany()
**?
向集合中批量插入多個文檔,適合初始化數據或批量導入。
?語法?:
db.collection.insertMany([{ <doc1> },{ <doc2> },...
])
?示例?:
插入 3 條用戶記錄:
db.users.insertMany([{name: "Bob",age: 30,email: "bob@example.com",hobbies: ["gaming", "coding"]},{name: "Charlie",age: 22,email: "charlie@example.com",isStudent: true},{name: "Diana",age: 28,email: "diana@example.com",hobbies: ["painting"],isStudent: false}
])
?輸出結果?:
{"acknowledged": true,"insertedIds": [ObjectId("650a8ba90f7d0e1a2c3b4d5f"),ObjectId("650a8ba90f7d0e1a2c3b4d60"),ObjectId("650a8ba90f7d0e1a2c3b4d61")]
}
?二、查詢操作(Query)??
用于從集合中檢索符合條件的文檔,核心方法是 find()
和 findOne()
。
?**1. 基礎查詢:find()
**?
返回所有符合條件的文檔(默認返回所有字段),支持條件過濾、投影(指定返回字段)、排序、分頁等。
?語法?:
db.collection.find(<query>, <projection>)
<query>
:查詢條件(類似 SQL 的WHERE
子句)。<projection>
:可選,指定返回的字段(1
表示包含,0
表示排除,不能混合使用_id
與其他字段外的1
和0
)。
?示例?:
??(1) 無過濾查詢(返回所有文檔)??
db.users.find() // 返回 users 集合的所有文檔
??(2) 條件查詢(過濾文檔)??
使用 ?查詢操作符?(如 $eq
、$gt
、$lt
、$in
等)定義條件。
-
?示例 1:精確匹配?(
$eq
)
查詢name
為 "Alice" 的文檔:db.users.find({ name: { $eq: "Alice" } }) // 等價于簡寫:db.users.find({ name: "Alice" })
-
?示例 2:范圍查詢?(
$gt
大于,$lt
小于)
查詢年齡大于 25 歲的用戶:db.users.find({ age: { $gt: 25 } })
-
?示例 3:包含查詢?(
$in
匹配數組中的任意值)
查詢郵箱在["alice@example.com", "diana@example.com"]
中的用戶:db.users.find({ email: { $in: ["alice@example.com", "diana@example.com"] } })
-
?示例 4:嵌套字段查詢?(點符號
.
訪問嵌套字段)
假設文檔有嵌套結構(如address.city
):// 插入一條帶嵌套字段的文檔: db.users.insertOne({name: "Eve",address: { city: "Beijing", zip: "100000" } })// 查詢城市為 Beijing 的用戶: db.users.find({ "address.city": "Beijing" })
-
?示例 5:正則表達式查詢?(
$regex
)
查詢name
以 "A" 開頭的用戶:db.users.find({ name: { $regex: "^A" } }) // 輸出 Alice(假設存在)
?2. 投影(Projection)??
控制返回的字段,減少網絡傳輸量。
?語法?:
db.collection.find(<query>, { <field1>: 1, <field2>: 0 })
_id
字段默認返回,若需排除需顯式設置"_id": 0
。
?示例?:
查詢所有用戶,但只返回 name
和 email
字段:
db.users.find({}, { name: 1, email: 1, _id: 0 })
?輸出結果?:
{ "name" : "Alice", "email" : "alice@example.com" }
{ "name" : "Bob", "email" : "bob@example.com" }
...
?3. 排序、分頁與統計?
-
?排序?:使用
sort()
方法(1
升序,-1
降序)。
示例:按年齡升序排序:db.users.find().sort({ age: 1 })
-
?分頁?:使用
skip(n)
(跳過前 n 條)和limit(m)
(限制返回 m 條)。
示例:查詢第 2 頁(每頁 2 條):db.users.find().skip(2).limit(2) // 跳過前 2 條,取 2 條
-
?統計數量?:使用
countDocuments()
(統計符合條件的文檔數)。
示例:統計年齡大于 25 歲的用戶數量:db.users.countDocuments({ age: { $gt: 25 } })
?**4. 單條文檔查詢:findOne()
**?
返回符合條件的第一條文檔?(適合快速獲取單條數據)。
?語法?:
db.collection.findOne(<query>, <projection>)
?示例?:
查詢 name
為 "Bob" 的第一條文檔:
db.users.findOne({ name: "Bob" })
?三、更新操作(Update)??
用于修改集合中的文檔,支持部分更新(僅修改指定字段)或全量替換。核心方法是 updateOne()
、updateMany()
和 replaceOne()
。
?**1. 更新單條文檔:updateOne()
**?
更新第一條符合條件的文檔,返回操作結果(包含是否成功、修改的文檔數等)。
?語法?:
db.collection.updateOne(<query>, // 查詢條件(匹配要更新的文檔)<update>, // 更新操作(使用更新操作符)<options> // 可選參數(如 upsert: true 表示不存在則插入)
)
?關鍵更新操作符?(必須配合使用,否則會覆蓋整個文檔):
$set
:設置字段的值(若字段不存在則創建)。$inc
:對數值型字段遞增/遞減。$push
:向數組字段末尾添加元素。$pull
:從數組字段中移除指定元素。$unset
:刪除指定字段。
?示例?:
??(1) 使用 $set
修改字段?
將 name
為 "Alice" 的用戶的 email
修改為 "alice.new@example.com":
db.users.updateOne({ name: "Alice" },{ $set: { email: "alice.new@example.com" } }
)
?輸出結果?:
{"acknowledged": true,"matchedCount": 1, // 匹配到的文檔數"modifiedCount": 1 // 實際修改的文檔數(若字段未變化則為 0)
}
??(2) 使用 $inc
遞增數值?
將 name
為 "Bob" 的用戶的 age
加 1:
db.users.updateOne({ name: "Bob" },{ $inc: { age: 1 } }
)
??(3) 使用 $push
向數組添加元素?
為 name
為 "Charlie" 的用戶的 hobbies
數組添加 "swimming":
db.users.updateOne({ name: "Charlie" },{ $push: { hobbies: "swimming" } }
)
??(4) 使用 $unset
刪除字段?
刪除 name
為 "Diana" 的用戶的 isStudent
字段:
db.users.updateOne({ name: "Diana" },{ $unset: { isStudent: "" } } // 值可以是任意(通常用空字符串)
)
?**2. 更新多條文檔:updateMany()
**?
更新所有符合條件的文檔(與 updateOne()
僅匹配數量不同)。
?示例?:
將所有年齡小于 28 歲的用戶的 isStudent
字段設為 true
:
db.users.updateMany({ age: { $lt: 28 } },{ $set: { isStudent: true } }
)
?**3. 全量替換文檔:replaceOne()
**?
用新文檔完全替換匹配到的第一條文檔(原字段會被覆蓋,僅保留 _id
)。
?語法?:
db.collection.replaceOne(<query>, // 查詢條件<replacementDoc> // 替換的新文檔(不能包含操作符如 $set)
)
?示例?:
將 name
為 "Eve" 的用戶替換為新文檔(僅保留 _id
):
db.users.replaceOne({ name: "Eve" },{newName: "Eve Smith", // 原 name 字段被覆蓋age: 30,email: "eve.smith@example.com"}
)
?四、刪除操作(Delete)??
用于刪除集合中的文檔,核心方法是 deleteOne()
和 deleteMany()
。
?**1. 刪除單條文檔:deleteOne()
**?
刪除第一條符合條件的文檔。
?語法?:
db.collection.deleteOne(<query>)
?示例?:
刪除 name
為 "Charlie" 的第一條文檔:
db.users.deleteOne({ name: "Charlie" })
?輸出結果?:
{"acknowledged": true,"deletedCount": 1 // 實際刪除的文檔數
}
?**2. 刪除多條文檔:deleteMany()
**?
刪除所有符合條件的文檔。
?示例?:
刪除所有年齡大于 30 歲的用戶:
db.users.deleteMany({ age: { $gt: 30 } })
?注意?:
- 刪除操作不可逆,建議先使用
find()
確認匹配的文檔,再執行刪除。 - 若需清空集合,可使用
db.collection.deleteMany({})
(謹慎!)。
?五、聚合查詢(Aggregate)??
用于復雜數據處理(如分組、統計、關聯等),通過聚合管道?(多個階段依次處理)實現。
?核心階段(Stage)??
$match
:過濾文檔(類似find()
)。$group
:按指定字段分組,計算聚合值(如求和、計數)。$project
:投影(指定輸出字段)。$sort
:排序。$limit
:限制輸出數量。
?示例:統計各城市的用戶數量?
需求:按 address.city
分組,統計每個城市的用戶數。
?聚合管道?:
db.users.aggregate([{ $match: { "address.city": { $exists: true } } }, // 過濾有城市的文檔{ $group: { // 分組統計_id: "$address.city", // 分組依據(城市名)count: { $sum: 1 } // 每組計數 +1}},{ $sort: { count: -1 } } // 按數量降序排序
])
?輸出結果?(假設):
[{ "_id" : "Beijing", "count" : 2 },{ "_id" : "Shanghai", "count" : 1 }
]
?總結?
MongoDB 的 CRUD 操作圍繞文檔的增刪改查展開,核心方法包括:
- ?插入?:
insertOne()
、insertMany()
- ?查詢?:
find()
(含投影、排序、分頁)、findOne()
- ?更新?:
updateOne()
(部分更新)、updateMany()
(批量更新)、replaceOne()
(全量替換) - ?刪除?:
deleteOne()
、deleteMany()
- ?高級查詢?:聚合管道(
aggregate()
)處理復雜統計。
實際使用中,需根據業務需求選擇合適的操作方法,并注意索引優化(如為常用查詢字段創建索引)以提升性能。