这节来说说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") } ]
1F
第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是因为什么?一直解决不了,求教
B1
@ 汪伽 “err” : “Cannot apply $inc modifier to non-number”,只有数字才能使用$inc,留一下你的值类型