MongoDB CRUD之U

Posted onetoinf

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MongoDB CRUD之U相关的知识,希望对你有一定的参考价值。

文档更新

命令 操作
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!!




以上是关于MongoDB CRUD之U的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB 学习笔记之 基本CRUD

MongoDB CRUD之R

MongoDB CRUD之D

《MongoDB入门教程》第06篇 CRUD之创建文档

《MongoDB入门教程》第06篇 CRUD之创建文档

《MongoDB入门教程》第06篇 CRUD之创建文档