mongodb 更新操作

默北 mongodb243,73310字数 11608阅读38分41秒阅读模式

这节来说说mongodb更新操作,可以使用update()函数来对数据进行更新。

语法:db.collection.update( criteria, objNew, upsert, multi )文章源自运维生存时间-https://www.ttlsa.com/mongodb/mongodb-update-operator/

update()接受的四个参数含义如下:文章源自运维生存时间-https://www.ttlsa.com/mongodb/mongodb-update-operator/

criteria : update的查询条件哪些记录需要更新,类似于SQL update语句的where子句。文章源自运维生存时间-https://www.ttlsa.com/mongodb/mongodb-update-operator/

objNew : update的对象和一些更新的操作符如$,$inc等等,也可以理解为SQL update语句的set子句。文章源自运维生存时间-https://www.ttlsa.com/mongodb/mongodb-update-operator/

upsert : 如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。文章源自运维生存时间-https://www.ttlsa.com/mongodb/mongodb-update-operator/

multi : 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。文章源自运维生存时间-https://www.ttlsa.com/mongodb/mongodb-update-operator/

注意:multi只对$操作有效。文章源自运维生存时间-https://www.ttlsa.com/mongodb/mongodb-update-operator/

1. 实例1文章源自运维生存时间-https://www.ttlsa.com/mongodb/mongodb-update-operator/

> db.mediaCollection.find({"Title" : "Matrix, The"}).toArray()
[
        {
                "_id" : ObjectId("53548225d85b463e729a2e57"),
                "Type" : "DVD",
                "Title" : "Matrix, The",
                "Released" : 1999,
                "Cast" : [
                        "Keanu Reeves",
                        "Carry-Anne Moss",
                        "Laurence Fishburne",
                        "Hugo Weaving",
                        "Gloria Foster",
                        "Joe Pantoliano"
                ]
        }
]
> db.mediaCollection.update({"Title" : "Matrix, The"},{"Type" : "DVD","Title" : "Matrix, The","Released" : 1999,"Genre":"Action"},true)
> db.mediaCollection.find({"Title" : "Matrix, The"}).toArray()
[
        {
                "_id" : ObjectId("53548225d85b463e729a2e57"),
                "Type" : "DVD",
                "Title" : "Matrix, The",
                "Released" : 1999,
                "Genre" : "Action"
        }
]

2. 使用save()命令来完成upset操作文章源自运维生存时间-https://www.ttlsa.com/mongodb/mongodb-update-operator/

语法:文章源自运维生存时间-https://www.ttlsa.com/mongodb/mongodb-update-operator/

db.collection.save(
   <document>,
   {
     writeConcern: <document>
   }
)
> db.mediaCollection.save( {"Type" : "DVD", "Title" : "Matrix, the", "Released" : "1999", "Genre" : "Action"})

3. 递增值$inc文章源自运维生存时间-https://www.ttlsa.com/mongodb/mongodb-update-operator/

$inc允许给一个指定的键加上增量,如果该键不存在将创建。文章源自运维生存时间-https://www.ttlsa.com/mongodb/mongodb-update-operator/

> db.mediaCollection.insert({ "Type" : "Manga", "Title" : "One Piece", "Volumes" : 612,"Read" : 520 })
> db.mediaCollection.update({"Title" : "One Piece"},{$inc:{"Read":5}})
> db.mediaCollection.find({"Title" : "One Piece"}).toArray()
[
        {
                "_id" : ObjectId("53560b8be0e2e4dd9bb0683d"),
                "Type" : "Manga",
                "Title" : "One Piece",
                "Volumes" : 612,
                "Read" : 525
        }
]

4. $set设定字段值文章源自运维生存时间-https://www.ttlsa.com/mongodb/mongodb-update-operator/

可以设定任何数据类型。文章源自运维生存时间-https://www.ttlsa.com/mongodb/mongodb-update-operator/

> db.mediaCollection.find({"Title" : "Matrix, the"}).toArray()
[
        {
                "_id" : ObjectId("535609c4e0e2e4dd9bb0683c"),
                "Type" : "DVD",
                "Title" : "Matrix, the",
                "Released" : "1999",
                "Genre" : "Action"
        }
]
> 
> 
> 
> db.mediaCollection.update({"Title" : "Matrix, the"}, {$set:{"Genre" : "Sci-Fi"}})
> db.mediaCollection.find({"Title" : "Matrix, the"}).toArray()
[
        {
                "_id" : ObjectId("535609c4e0e2e4dd9bb0683c"),
                "Type" : "DVD",
                "Title" : "Matrix, the",
                "Released" : "1999",
                "Genre" : "Sci-Fi"
        }
]

5. $unset删除指定字段文章源自运维生存时间-https://www.ttlsa.com/mongodb/mongodb-update-operator/

> db.mediaCollection.find({"Title" : "Matrix, the"}).toArray()
[
        {
                "_id" : ObjectId("535609c4e0e2e4dd9bb0683c"),
                "Type" : "DVD",
                "Title" : "Matrix, the",
                "Released" : "1999",
                "Genre" : "Sci-Fi"
        }
]
> db.mediaCollection.update({"Title" : "Matrix, the"}, {$unset:{"Genre" : 1}})
> db.mediaCollection.find({"Title" : "Matrix, the"}).toArray()
[
        {
                "Released" : "1999",
                "Title" : "Matrix, the",
                "Type" : "DVD",
                "_id" : ObjectId("535609c4e0e2e4dd9bb0683c")
        }
]

6. $push追加一个值到指定字段文章源自运维生存时间-https://www.ttlsa.com/mongodb/mongodb-update-operator/

$push允许追加一个值到指定字段。如果该字段是一个现有的数组,那么该值将被添加。如果该字段尚不存在,则该字段将被设置为该值的数组。如果该字段存在,但它不是一个数组,将报错。文章源自运维生存时间-https://www.ttlsa.com/mongodb/mongodb-update-operator/

$push针对数组类型的。文章源自运维生存时间-https://www.ttlsa.com/mongodb/mongodb-update-operator/

> db.mediaCollection.find({"ISBN" : "987-1-4302-3051-9"}).toArray()
[
        {
                "_id" : ObjectId("5353462f93efef02c962da71"),
                "Type" : "Book",
                "Title" : "Definitive Guide to MongoDB, the",
                "ISBN" : "987-1-4302-3051-9",
                "Publisher" : "Apress",
                "Author" : [
                        "Membrey, Peter",
                        "Plugge, Eelco",
                        "Hawkins, Tim"
                ]
        }
]
> 
> db.mediaCollection.update({"ISBN" : "987-1-4302-3051-9"},{$push:{Author:"Griffin, Stewie"}})
> db.mediaCollection.update({"ISBN" : "987-1-4302-3051-9"},{$push:{Title:"Griffin, Stewie"}})
Cannot apply $push/$pushAll modifier to non-array
> db.mediaCollection.find({"ISBN" : "987-1-4302-3051-9"}).toArray()
[
        {
                "Author" : [
                        "Membrey, Peter",
                        "Plugge, Eelco",
                        "Hawkins, Tim",
                        "Griffin, Stewie"
                ],
                "ISBN" : "987-1-4302-3051-9",
                "Publisher" : "Apress",
                "Title" : "Definitive Guide to MongoDB, the",
                "Type" : "Book",
                "_id" : ObjectId("5353462f93efef02c962da71")
        }
]

7. 向一个数组添加多个值文章源自运维生存时间-https://www.ttlsa.com/mongodb/mongodb-update-operator/

$pushAll与$push类似,规则相同。向指定的数组添加多个值。文章源自运维生存时间-https://www.ttlsa.com/mongodb/mongodb-update-operator/

> db.mediaCollection.find({"ISBN" : "987-1-4302-3051-9"}).toArray()
[
        {
                "Author" : [
                        "Membrey, Peter",
                        "Plugge, Eelco",
                        "Hawkins, Tim",
                        "Griffin, Stewie"
                ],
                "ISBN" : "987-1-4302-3051-9",
                "Publisher" : "Apress",
                "Title" : "Definitive Guide to MongoDB, the",
                "Type" : "Book",
                "_id" : ObjectId("5353462f93efef02c962da71")
        }
]
> db.mediaCollection.update({"ISBN" : "987-1-4302-3051-9"},{$pushAll:{Author: ["Griffin,Louis","Griffin, Peter"]}})
> db.mediaCollection.find({"ISBN" : "987-1-4302-3051-9"}).toArray()
[
        {
                "Author" : [
                        "Membrey, Peter",
                        "Plugge, Eelco",
                        "Hawkins, Tim",
                        "Griffin, Stewie",
                        "Griffin,Louis",
                        "Griffin, Peter"
                ],
                "ISBN" : "987-1-4302-3051-9",
                "Publisher" : "Apress",
                "Title" : "Definitive Guide to MongoDB, the",
                "Type" : "Book",
                "_id" : ObjectId("5353462f93efef02c962da71")
        }
]

8.  $addToSet将数据添加到数组

向数组添加数据的另一种方式。然而,该操作只有该数据不存在时添加。同时,只能指定一个参数,如果要指定多个参数可以使用$each.

> db.mediaCollection.find({"ISBN" : "987-1-4302-3051-9"}).toArray()
[
        {
                "Author" : [
                        "Membrey, Peter",
                        "Plugge, Eelco",
                        "Hawkins, Tim",
                        "Griffin, Stewie",
                        "Griffin,Louis",
                        "Griffin, Peter"
                ],
                "ISBN" : "987-1-4302-3051-9",
                "Publisher" : "Apress",
                "Title" : "Definitive Guide to MongoDB, the",
                "Type" : "Book",
                "_id" : ObjectId("5353462f93efef02c962da71")
        }
]
> 
> 
> db.mediaCollection.update({"ISBN" : "987-1-4302-3051-9"},{$addToSet:{Author:"Griffin, Stewie"}})
> db.mediaCollection.find({"ISBN" : "987-1-4302-3051-9"}).toArray()
[
        {
                "Author" : [
                        "Membrey, Peter",
                        "Plugge, Eelco",
                        "Hawkins, Tim",
                        "Griffin, Stewie",
                        "Griffin,Louis",
                        "Griffin, Peter"
                ],
                "ISBN" : "987-1-4302-3051-9",
                "Publisher" : "Apress",
                "Title" : "Definitive Guide to MongoDB, the",
                "Type" : "Book",
                "_id" : ObjectId("5353462f93efef02c962da71")
        }
]
> db.mediaCollection.update({"ISBN" : "987-1-4302-3051-9"},{$addToSet:{Author:{$each:["Griffin, Stewie","Griffin, Meg"]}}})
> db.mediaCollection.find({"ISBN" : "987-1-4302-3051-9"}).toArray()
[
        {
                "Author" : [
                        "Membrey, Peter",
                        "Plugge, Eelco",
                        "Hawkins, Tim",
                        "Griffin, Stewie",
                        "Griffin,Louis",
                        "Griffin, Peter",
                        "Griffin, Meg"
                ],
                "ISBN" : "987-1-4302-3051-9",
                "Publisher" : "Apress",
                "Title" : "Definitive Guide to MongoDB, the",
                "Type" : "Book",
                "_id" : ObjectId("5353462f93efef02c962da71")
        }
]

9. 从数组中删除元素

有多种方式从数组中删除元素: $pop, $pull, $pullAll。

$pop可以删除数组第一个或最后一个元素。1最后一个元素,-1第一个元素。

$pull从数组中删除指定的元素。

$pullAll从数组中删除多个不同的元素。

> db.mediaCollection.find({"ISBN" : "987-1-4302-3051-9"}).toArray()
[
        {
                "Author" : [
                        "Membrey, Peter",
                        "Plugge, Eelco",
                        "Hawkins, Tim",
                        "Griffin, Stewie",
                        "Griffin,Louis",
                        "Griffin, Peter",
                        "Griffin, Meg"
                ],
                "ISBN" : "987-1-4302-3051-9",
                "Publisher" : "Apress",
                "Title" : "Definitive Guide to MongoDB, the",
                "Type" : "Book",
                "_id" : ObjectId("5353462f93efef02c962da71")
        }
]
> db.mediaCollection.update({"ISBN" : "987-1-4302-3051-9"},{$pop:{Author:1}})
> db.mediaCollection.find({"ISBN" : "987-1-4302-3051-9"}).toArray()
[
        {
                "Author" : [
                        "Membrey, Peter",
                        "Plugge, Eelco",
                        "Hawkins, Tim",
                        "Griffin, Stewie",
                        "Griffin,Louis",
                        "Griffin, Peter"
                ],
                "ISBN" : "987-1-4302-3051-9",
                "Publisher" : "Apress",
                "Title" : "Definitive Guide to MongoDB, the",
                "Type" : "Book",
                "_id" : ObjectId("5353462f93efef02c962da71")
        }
]
> db.mediaCollection.update({"ISBN" : "987-1-4302-3051-9"},{$pop:{Author:-1}})
> db.mediaCollection.find({"ISBN" : "987-1-4302-3051-9"}).toArray()
[
        {
                "Author" : [
                        "Plugge, Eelco",
                        "Hawkins, Tim",
                        "Griffin, Stewie",
                        "Griffin,Louis",
                        "Griffin, Peter"
                ],
                "ISBN" : "987-1-4302-3051-9",
                "Publisher" : "Apress",
                "Title" : "Definitive Guide to MongoDB, the",
                "Type" : "Book",
                "_id" : ObjectId("5353462f93efef02c962da71")
        }
]
> db.mediaCollection.find({"ISBN" : "987-1-4302-3051-9"}).toArray()
[
        {
                "Author" : [
                        "Hawkins, Tim",
                        "Griffin, Stewie",
                        "Griffin,Louis",
                        "Griffin, Peter",
                        "Plugge, Eelco",
                        "Griffin, Stewie"
                ],
                "ISBN" : "987-1-4302-3051-9",
                "Publisher" : "Apress",
                "Title" : "Definitive Guide to MongoDB, the",
                "Type" : "Book",
                "_id" : ObjectId("5353462f93efef02c962da71")
        }
]
> db.mediaCollection.update({"ISBN" : "987-1-4302-3051-9"},{$pull:{Author:"Griffin, Stewie"}})
> db.mediaCollection.find({"ISBN" : "987-1-4302-3051-9"}).toArray()
[
        {
                "Author" : [
                        "Hawkins, Tim",
                        "Griffin,Louis",
                        "Griffin, Peter",
                        "Plugge, Eelco"
                ],
                "ISBN" : "987-1-4302-3051-9",
                "Publisher" : "Apress",
                "Title" : "Definitive Guide to MongoDB, the",
                "Type" : "Book",
                "_id" : ObjectId("5353462f93efef02c962da71")
        }
]
> db.mediaCollection.find({"ISBN" : "987-1-4302-3051-9"}).toArray()
[
        {
                "Author" : [
                        "Hawkins, Tim",
                        "Griffin,Louis",
                        "Griffin, Peter",
                        "Plugge, Eelco"
                ],
                "ISBN" : "987-1-4302-3051-9",
                "Publisher" : "Apress",
                "Title" : "Definitive Guide to MongoDB, the",
                "Type" : "Book",
                "_id" : ObjectId("5353462f93efef02c962da71")
        }
]
> db.mediaCollection.update({"ISBN" : "987-1-4302-3051-9"},{$pullAll:{Author:["Griffin,Louis", "Griffin, Peter",]}})
> db.mediaCollection.find({"ISBN" : "987-1-4302-3051-9"}).toArray()
[
        {
                "Author" : [
                        "Hawkins, Tim",
                        "Plugge, Eelco"
                ],
                "ISBN" : "987-1-4302-3051-9",
                "Publisher" : "Apress",
                "Title" : "Definitive Guide to MongoDB, the",
                "Type" : "Book",
                "_id" : ObjectId("5353462f93efef02c962da71")
        }
]

10. 指定位置来匹配数组

可以使用$操作符在查询中指定的查询匹配的数组项的位置。

> db.mediaCollection.update( { "Title" : "Nevermind" }, {$addToSet : { Tracklist :{"Track" : 2,"Title": "Been a son", "Length":"2:23"} } } )
> db.mediaCollection.find({"Title" : "Nevermind"}).toArray()
[
        {
                "_id" : ObjectId("5353463193efef02c962da73"),
                "Type" : "CD",
                "Artist" : "Nirvana",
                "Title" : "Nevermind",
                "Tracklist" : [
                        {
                                "Track" : "1",
                                "Title" : "Smells like teen spirit",
                                "Length" : "5:02"
                        },
                        {
                                "Track" : "2",
                                "Title" : "In Bloom",
                                "Length" : "4:15"
                        }
                ]
        },
        {
                "Artist" : "Nirvana",
                "Title" : "Nevermind",
                "Tracklist" : [
                        {
                                "Track" : 2,
                                "Title" : "Been a son",
                                "Length" : "2:23"
                        }
                ],
                "Type" : "CD",
                "_id" : ObjectId("5353462f93efef02c962da72")
        }
]

> db.mediaCollection.update( { "Tracklist.Title" : "Been a son"},{$inc:{"Tracklist.$.Track" : 1} } )
> db.mediaCollection.find({"Title" : "Nevermind"}).toArray()
[
        {
                "_id" : ObjectId("5353463193efef02c962da73"),
                "Type" : "CD",
                "Artist" : "Nirvana",
                "Title" : "Nevermind",
                "Tracklist" : [
                        {
                                "Track" : "1",
                                "Title" : "Smells like teen spirit",
                                "Length" : "5:02"
                        },
                        {
                                "Track" : "2",
                                "Title" : "In Bloom",
                                "Length" : "4:15"
                        }
                ]
        },
        {
                "Artist" : "Nirvana",
                "Title" : "Nevermind",
                "Tracklist" : [
                        {
                                "Track" : 3,
                                "Title" : "Been a son",
                                "Length" : "2:23"
                        }
                ],
                "Type" : "CD",
                "_id" : ObjectId("5353462f93efef02c962da72")
        }
]

11. 原子操作

要么成功要么回滚。

12. 获取最近一次更改信息

> db.$cmd.findOne({getlasterror:1})
{ "n" : 0, "connectionId" : 1, "err" : null, "ok" : 1 }
> db.mediaCollection.update( { "Tracklist.Title" : "In Bloom"},{$inc:{"Tracklist.$.Track" : 1} } )
Cannot apply $inc modifier to non-number
> db.$cmd.findOne({getlasterror:1})
{
        "err" : "Cannot apply $inc modifier to non-number",
        "code" : 10140,
        "n" : 0,
        "connectionId" : 1,
        "ok" : 1
}

13. ABA问题

ABA Problem就是譬如一个共享变量A,需要update到一个新的值C,而记录这个变量的值是B,此时A=B;在记录和update的这段时间中,这个共享变量被其余的job或者是thread操作修改了很多次,但是在update之前,还是回到了最开始的值。这就叫做ABA Problem。

避免方法:

1). 使用整体对象查询表达式代替_id和comments.by。

2). 使用$set来更新。

3). 版本变量控制。

4). 如果可能,使用$来代替update-if-current操作序列。

14. findAndModify()

语法:

db.collection.findAndModify({
    query: <document>,
    sort: <document>,
    remove: <boolean>,
    update: <document>,
    new: <boolean>,
    fields: <document>,
    upsert: <boolean>
});

原子更新,该命令查询并修改文档。

> db.mediaCollection.findAndModify( { "Title" : "One Piece",sort:{"Title": -1}, remove:true} )
{
        "_id" : ObjectId("53560b8be0e2e4dd9bb0683d"),
        "Type" : "Manga",
        "Title" : "One Piece",
        "Volumes" : 612,
        "Read" : 525
}
> db.mediaCollection.find({"Title" : "One Piece"}).toArray()
[ ]
> db.mediaCollection.find({"ISBN" : "987-1-4302-3051-9"}).sort({"Title":-1}).toArray()
[
        {
                "Author" : [
                        "Hawkins, Tim",
                        "Plugge, Eelco"
                ],
                "ISBN" : "987-1-4302-3051-9",
                "Publisher" : "Apress",
                "Title" : "Definitive Guide to MongoDB, the",
                "Type" : "Book",
                "_id" : ObjectId("5353462f93efef02c962da71")
        }
]
> db.mediaCollection.findAndModify( { query: { "ISBN" : "987-1-4302-3051-9" }, sort:{"Title":-1}, update: {$set: {"Title" : " Different Title"} } } )
{
        "Author" : [
                "Hawkins, Tim",
                "Plugge, Eelco"
        ],
        "ISBN" : "987-1-4302-3051-9",
        "Publisher" : "Apress",
        "Title" : "Definitive Guide to MongoDB, the",
        "Type" : "Book",
        "_id" : ObjectId("5353462f93efef02c962da71")
}
> db.mediaCollection.find({"ISBN" : "987-1-4302-3051-9"}).sort({"Title":-1}).toArray()
[
        {
                "Author" : [
                        "Hawkins, Tim",
                        "Plugge, Eelco"
                ],
                "ISBN" : "987-1-4302-3051-9",
                "Publisher" : "Apress",
                "Title" : " Different Title",
                "Type" : "Book",
                "_id" : ObjectId("5353462f93efef02c962da71")
        }
]

上面实例更新“Title”并返回旧文档。要返回更改后的文档按下面操作:

> db.mediaCollection.find({"ISBN" : "987-1-4302-3051-9"}).sort({"Title":-1}).toArray()
[
        {
                "Author" : [
                        "Hawkins, Tim",
                        "Plugge, Eelco"
                ],
                "ISBN" : "987-1-4302-3051-9",
                "Publisher" : "Apress",
                "Title" : " Different Title",
                "Type" : "Book",
                "_id" : ObjectId("5353462f93efef02c962da71")
        }
]
> db.mediaCollection.findAndModify( { query: { "ISBN" : "987-1-4302-3051-9" }, sort:{"Title":-1}, update: {$set: {"Title" : " Different Title 2"} },new:true } )
{
        "Author" : [
                "Hawkins, Tim",
                "Plugge, Eelco"
        ],
        "ISBN" : "987-1-4302-3051-9",
        "Publisher" : "Apress",
        "Title" : " Different Title 2",
        "Type" : "Book",
        "_id" : ObjectId("5353462f93efef02c962da71")
}
> db.mediaCollection.find({"ISBN" : "987-1-4302-3051-9"}).sort({"Title":-1}).toArray()
[
        {
                "Author" : [
                        "Hawkins, Tim",
                        "Plugge, Eelco"
                ],
                "ISBN" : "987-1-4302-3051-9",
                "Publisher" : "Apress",
                "Title" : " Different Title 2",
                "Type" : "Book",
                "_id" : ObjectId("5353462f93efef02c962da71")
        }
]
weinxin
我的微信
微信公众号
扫一扫关注运维生存时间公众号,获取最新技术文章~
默北
  • 本文由 发表于 01/06/2014 01:00:36
  • 转载请务必保留本文链接:https://www.ttlsa.com/mongodb/mongodb-update-operator/
评论  2  访客  2
    • 汪伽
      汪伽 9

      第12条, db.mediaCollection.update( { “Tracklist.Title” : “In Bloom”},{$inc:{“Tracklist.$.Track” : 1} } )
      Cannot apply $inc modifier to non-number
      > db.$cmd.findOne({getlasterror:1})
      {
      “err” : “Cannot apply $inc modifier to non-number”,
      “code” : 10140,
      “n” : 0,
      “connectionId” : 1,
      “ok” : 1
      }

      这个error是因为什么?一直解决不了,求教

        • 运维生存时间网
          运维生存时间网 7

          @ 汪伽 “err” : “Cannot apply $inc modifier to non-number”,只有数字才能使用$inc,留一下你的值类型

      评论已关闭!