文档更新
命令 | 操作 |
---|---|
db.collection.update (query, update, options) |
修改集合中的现有文档或文档。 该方法可以根据更新参数修改现有文档 或文档的特定字段, 或完全替换现有文档。 |
db.collection.updateMany (filter, update, options) |
基于过滤器更新集合中的多个文档。 |
db.collection.updateOne (filter, update, options) |
根据过滤器更新集合中的单个文档。 |
db.collection.replaceOne (filter, replacement, options) |
根据过滤器替换集合中的单个文档。 |
更多参考
Update
格式
db.collection.update(
<query>,
<update>,
{
upsert: <boolean>,
multi: <boolean>,
writeConcern: <document>,
collation: <document>,
arrayFilters: [ <filterdocument1>, ... ]
}
)
全覆盖更新
- 不加任何参数
14 > db.set2test.find({ x: { $lt:10 } })
{ "_id" : ObjectId("5a7943273fdd5fec85460638"), "x" : 3 }
...
{ "_id" : ObjectId("5a7943273fdd5fec8546063e"), "x" : 9 }
15 > db.set2test.update({ x: { $lt:10 } }, { x: 999 })
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
16 > db.set2test.find({ x: { $lt:10 } })
{ "_id" : ObjectId("5a7943273fdd5fec85460639"), "x" : 4 }
...
{ "_id" : ObjectId("5a7943273fdd5fec8546063e"), "x" : 9 }
会默认更新第一条匹配的数据.
21 > db.set2test.insert({
... x : 3,
... y : 4,
... z : 5
... })
WriteResult({ "nInserted" : 1 })
22 > db.set2test.update({ x:3 }, { x:6, y:8, z:10 })
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
23 > db.set2test.find( { z:10 } )
{ "_id" : ObjectId("5a798f6052866ce905d74021"), "x" : 6, "y" : 8, "z" : 10 }
24 > db.set2test.update({ x:6 }, { x:666 })
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
25 > db.set2test.find( { x:666 } )
{ "_id" : ObjectId("5a7943273fdd5fec8546063b"), "x" : 666 }
可以看到不指定字段进行更新的话,会默认将所有的字段进行覆盖,这样的操作其实很危险.
部分更新
- 使用循环和
$set
添加新的字段
29 > for(i = 3; i < 100; i++)db.set2test.update({ x:i }, { $set: { twice:i*2 } })
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
30 > db.set2test.find()
{ "_id" : 5, "x" : 3, "twice" : 6 }
{ "_id" : 6, "x" : 4, "twice" : 8 }
{ "_id" : 7, "x" : 5, "twice" : 10 }
{ "_id" : 8, "x" : 6, "twice" : 12 }
{ "_id" : 9, "x" : 7, "twice" : 14 }
{ "_id" : 10, "x" : 8, "twice" : 16 }
{ "_id" : 11, "x" : 9, "twice" : 18 }
...
这样就不会覆盖所有的数据了.
- 使用参数multi更新所有符合条件的数据和
$unset
删除字段
34 > db.set2test.find({ x:10 })
{ "_id" : 5, "x" : 10, "twice" : "" }
{ "_id" : 6, "x" : 10, "twice" : "" }
{ "_id" : 7, "x" : 10, "twice" : "" }
{ "_id" : 8, "x" : 10, "twice" : "" }
{ "_id" : 9, "x" : 10, "twice" : "" }
{ "_id" : 10, "x" : 10, "twice" : "" }
{ "_id" : 11, "x" : 10, "twice" : "" }
{ "_id" : 12, "x" : 10, "twice" : 20 }
35 > db.set2test.update(
{ x:10 },
{
$unset:{ twice: "" },
$set:{ x:17 }
},
{ multi:true }
)
WriteResult({ "nMatched" : 8, "nUpserted" : 0, "nModified" : 8 })
36 > db.set2test.find({ x:17 })
{ "_id" : 5, "x" : 17 }
{ "_id" : 6, "x" : 17 }
{ "_id" : 7, "x" : 17 }
{ "_id" : 8, "x" : 17 }
{ "_id" : 9, "x" : 17 }
{ "_id" : 10, "x" : 17 }
{ "_id" : 11, "x" : 17 }
{ "_id" : 12, "x" : 17 }
{ "_id" : 19, "x" : 17, "twice" : 34 }
注: multi只能和$set使用
匹配不到时创建
- 使用upsert
37 > db.books.find()
38 > db.books.update(
... { item: "ZZZ135" },
... {
... item: "ZZZ135",
... stock: 5,
... tags: [ "database" ]
... },
... { upsert: true }
... )
WriteResult({
"nMatched" : 0,
"nUpserted" : 1,
"nModified" : 0,
"_id" : ObjectId("5a79977f8c823207073133c4")
})
39 > db.books.find()
{ "_id" : ..., "item" : "ZZZ135", "stock" : 5, "tags" : [ "database" ] }
- 联合使用参数multi和upsert
3 > db.books.find().pretty()
{
"_id" : 5,
"item" : "EFG222",
"stock" : 18,
"info" : {
"publisher" : "0000",
"pages" : 70
},
"reorder" : true
}
{
"_id" : 6,
"item" : "EFG222",
"stock" : 15,
"info" : {
"publisher" : "1111",
"pages" : 72
},
"reorder" : true
}
准备更新的js文档:
db.books.update(
{ item: "EFG222" },
{ $set: { reorder: false, tags: [ "literature", "translated" ] } },
{ upsert: true, multi: true }
)
shell 中加载文档
4 > load("query_books.js")
true
5 > db.books.find().pretty()
{
"_id" : 5,
"item" : "EFG222",
"stock" : 18,
"info" : {
"publisher" : "0000",
"pages" : 70
},
"reorder" : false,
"tags" : [
"literature",
"translated"
]
}
{
"_id" : 6,
"item" : "EFG222",
"stock" : 15,
"info" : {
"publisher" : "1111",
"pages" : 72
},
"reorder" : false,
"tags" : [
"literature",
"translated"
]
}
- colllation指定排序
9 > db.mycoll0.find()
{ "_id" : 1, "category" : "café", "status" : "A" }
{ "_id" : 2, "category" : "cafe", "status" : "a" }
{ "_id" : 3, "category" : "cafE", "status" : "a" }
collation参数见这里
准备的更新文档如下
db.myColl.update(
{ category: "cafe" },
{ $set: { status: "Updated" } },
{ collation: { locale: "fr", strength: 1 } }
);
加载js文档
10 > load("updata_mycoll9.js")
true
11 > db.mycoll0.find()
{ "_id" : 1, "category" : "café", "status" : "A" }
{ "_id" : 2, "category" : "cafe", "status" : "a" }
{ "_id" : 3, "category" : "cafE", "status" : "a" }
- 使用参数arrayFilter更新数组(New in version 3.6.)
15 > db.students.find()
{ "_id" : 1, "grades" : [ 95, 92, 90 ] }
{ "_id" : 2, "grades" : [ 98, 100, 102 ] }
{ "_id" : 3, "grades" : [ 95, 110, 100 ] }
准备的更新文档如下
db.students.update(
{ grades: { $gte: 100 } },
{ $set: { "grades.$[element]" : 100 } },
{
multi: true,
arrayFilters: [ { "element": { $gte: 100 } } ]
}
)
加载js文档
23 > load("update_students.js")
true
因为我的版本是3.4,所以不会生效
正常变更后的数据为:
{ "_id" : 1, "grades" : [ 95, 92, 90 ] }
{ "_id" : 2, "grades" : [ 98, 100, 100 ] }
{ "_id" : 3, "grades" : [ 95, 100, 100 ] }
这是来自官网的教程 , 只能以后再看略.
updateOne
格式
db.collection.updateOne(
<filter>,
<update>,
{
upsert: <boolean>,
writeConcern: <document>,
collation: <document>,
arrayFilters: [ <filterdocument1>, ... ]
}
)
可以看到参数与Update一样的,但顾名思义的应该是只能更新一条数据
使用参数upsert
数据
27 > load("data_restaurant.js")
true
28 > db.restaurant.find()
{ "_id" : 1, "name" : "Central Perk Cafe", "Borough" : "Manhattan", "violations" : 3 }
{ "_id" : 2, "name" : "Rock A Feller Bar and Grill", "Borough" : "Queens", "violations" : 2 }
{ "_id" : 3, "name" : "Empire State Pub", "Borough" : "Brooklyn", "violations" : "0" }
操作
29 > try {
... db.restaurant.updateOne(
... { "name" : "Pizza Rat's Pizzaria" },
... { $set: {"_id" : 4, "violations" : 7, "borough" : "Manhattan" } },
... { upsert: true }
... );
... } catch (e) {
... print(e);
... }
{
"acknowledged" : true,
"matchedCount" : 0,
"modifiedCount" : 0,
"upsertedId" : 4
}
30 > db.restaurant.find()
{ "_id" : 1, "name" : "Central Perk Cafe", "Borough" : "Manhattan", "violations" : 3 }
{ "_id" : 2, "name" : "Rock A Feller Bar and Grill", "Borough" : "Queens", "violations" : 2 }
{ "_id" : 3, "name" : "Empire State Pub", "Borough" : "Brooklyn", "violations" : "0" }
{ "_id" : 4, "name" : "Pizza Rat's Pizzaria", "violations" : 7, "borough" : "Manhattan" }
将违规10次以上的餐饮进行关停
31 > try {
... db.restaurant.updateOne(
... { "violations" : { $gt: 10} },
... { $set: { "Closed" : true } },
... { upsert: true }
... );
... } catch (e) {
... print(e);
... }
{
"acknowledged" : true,
"matchedCount" : 0,
"modifiedCount" : 0,
"upsertedId" : ObjectId("5a79c54fcf6c4175a57b2bff")
}
32 > db.restaurant.find()
{ "_id" : 1, "name" : "Central Perk Cafe", "Borough" : "Manhattan", "violations" : 3 }
{ "_id" : 2, "name" : "Rock A Feller Bar and Grill", "Borough" : "Queens", "violations" : 2 }
{ "_id" : 3, "name" : "Empire State Pub", "Borough" : "Brooklyn", "violations" : "0" }
{ "_id" : 4, "name" : "Pizza Rat's Pizzaria", "violations" : 7, "borough" : "Manhattan" }
{ "_id" : ObjectId("5a79c54fcf6c4175a57b2bff"), "Closed" : true }
updataMany
格式
db.collection.updateMany(
<filter>,
<update>,
{
upsert: <boolean>,
writeConcern: <document>,
collation: <document>,
arrayFilters: [ <filterdocument1>, ... ]
}
)
无参更新
39 > db.restaurant.find()
{ "_id" : 1, "name" : "Central Perk Cafe", "violations" : 3 }
{ "_id" : 2, "name" : "Rock A Feller Bar and Grill", "violations" : 2 }
{ "_id" : 3, "name" : "Empire State Sub", "violations" : 5 }
{ "_id" : 4, "name" : "Pizza Rat's Pizzaria", "violations" : 8 }
40 > try {
... db.restaurant.updateMany(
... { violations: { $gt: 4 } },
... { $set: { "Review" : true } }
... );
... } catch (e) {
... print(e);
... }
{ "acknowledged" : true, "matchedCount" : 2, "modifiedCount" : 2 }
41 > db.restaurant.find()
{ "_id" : 1, "name" : "Central Perk Cafe", "violations" : 3 }
{ "_id" : 2, "name" : "Rock A Feller Bar and Grill", "violations" : 2 }
{ "_id" : 3, "name" : "Empire State Sub", "violations" : 5, "Review" : true }
{ "_id" : 4, "name" : "Pizza Rat's Pizzaria", "violations" : 8, "Review" : true }
可以看到违规4次以上的餐饮将进行复查
使用参数upsert
43 > db.inspectors.find()
{ "_id" : 92412, "inspector" : "F. Drebin", "Sector" : 1, "Patrolling" : true }
{ "_id" : 92413, "inspector" : "J. Clouseau", "Sector" : 2, "Patrolling" : false }
{ "_id" : 92414, "inspector" : "J. Clouseau", "Sector" : 3, "Patrolling" : true }
{ "_id" : 92415, "inspector" : "R. Coltrane", "Sector" : 3, "Patrolling" : false }
44 > try {
... db.inspectors.updateMany(
... { "Sector" : { $gt : 4 }, "inspector" : "R. Coltrane" },
... { $set: { "Patrolling" : false } },
... { upsert: true }
... );
... } catch (e) {
... print(e);
... }
{
"acknowledged" : true,
"matchedCount" : 0,
"modifiedCount" : 0,
"upsertedId" : ObjectId("5a79c792cf6c4175a57b2c12")
}
45 > db.inspectors.find()
{ "_id" : 92412, "inspector" : "F. Drebin", "Sector" : 1, "Patrolling" : true }
{ "_id" : 92413, "inspector" : "J. Clouseau", "Sector" : 2, "Patrolling" : false }
{ "_id" : 92414, "inspector" : "J. Clouseau", "Sector" : 3, "Patrolling" : true }
{ "_id" : 92415, "inspector" : "R. Coltrane", "Sector" : 3, "Patrolling" : false }
{ "_id" : ObjectId("....."), "inspector" : "R. Coltrane", "Patrolling" : false }
replaceOne
格式
db.collection.replaceOne(
<filter>,
<replacement>,
{
upsert: <boolean>,
writeConcern: <document>,
collation: <document>
}
)
这一条命令会取代原文档
无参更新
> db.restaurant.find()
{ "_id" : 1, "name" : "Central Perk Cafe", "violations" : 3 }
{ "_id" : 2, "name" : "Rock A Feller Bar and Grill", "violations" : 2 }
{ "_id" : 3, "name" : "Empire State Sub", "violations" : 5 }
{ "_id" : 4, "name" : "Pizza Rat's Pizzaria", "violations" : 8 }
> try {
... db.restaurant.replaceOne(
... { "name" : "Central Perk Cafe" },
... { "name" : "Central Pork Cafe", "Borough" : "Manhattan" }
... );
... } catch (e){
... print(e);
... }
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
> db.restaurant.find()
{ "_id" : 1, "name" : "Central Pork Cafe", "Borough" : "Manhattan" }
{ "_id" : 2, "name" : "Rock A Feller Bar and Grill", "violations" : 2 }
{ "_id" : 3, "name" : "Empire State Sub", "violations" : 5 }
{ "_id" : 4, "name" : "Pizza Rat's Pizzaria", "violations" : 8 }
使用参数upsert
> db.restaurant.find()
{ "_id" : 1, "name" : "Central Perk Cafe", "violations" : 3 }
{ "_id" : 2, "name" : "Rock A Feller Bar and Grill", "violations" : 2 }
{ "_id" : 3, "name" : "Empire State Sub", "violations" : 5 }
> try {
... db.restaurant.replaceOne(
... { "name" : "Pizza Rat's Pizzaria" },
... { "_id": 4, "name" : "Pizza Rat's Pizzaria", "Borough" : "Manhattan", "violations" : 8 },
... { upsert: true }
... );
... } catch (e){
... print(e);
... }
{
"acknowledged" : true,
"matchedCount" : 0,
"modifiedCount" : 0,
"upsertedId" : 4
}
> db.restaurant.find()
{ "_id" : 1, "name" : "Central Perk Cafe", "violations" : 3 }
{ "_id" : 2, "name" : "Rock A Feller Bar and Grill", "violations" : 2 }
{ "_id" : 3, "name" : "Empire State Sub", "violations" : 5 }
{ "_id" : 4, "name" : "Pizza Rat's Pizzaria", "Borough" : "Manhattan", "violations" : 8 }
其他参数先不看吧,似乎很多是3.6!!