- A+
这节来说说mongodb更新操作,可以使用update()函数来对数据进行更新。
语法:db.collection.update( criteria, objNew, upsert, multi )
update()接受的四个参数含义如下:
criteria : update的查询条件哪些记录需要更新,类似于SQL update语句的where子句。
objNew : update的对象和一些更新的操作符如$,$inc等等,也可以理解为SQL update语句的set子句。
upsert : 如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。
multi : 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。
注意:multi只对$操作有效。
1. 实例1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
> 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操作
语法:
1 2 3 4 5 6 |
db.collection.save( <document>, { writeConcern: <document> } ) |
1 |
> db.mediaCollection.save( {"Type" : "DVD", "Title" : "Matrix, the", "Released" : "1999", "Genre" : "Action"}) |
3. 递增值$inc
$inc允许给一个指定的键加上增量,如果该键不存在将创建。
1 2 3 4 5 6 7 8 9 10 11 12 |
> 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设定字段值
可以设定任何数据类型。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
> 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删除指定字段
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
> 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追加一个值到指定字段
$push允许追加一个值到指定字段。如果该字段是一个现有的数组,那么该值将被添加。如果该字段尚不存在,则该字段将被设置为该值的数组。如果该字段存在,但它不是一个数组,将报错。
$push针对数组类型的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
> 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. 向一个数组添加多个值
$pushAll与$push类似,规则相同。向指定的数组添加多个值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
> 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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
> 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从数组中删除多个不同的元素。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
> 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") } ] |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
> 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") } ] |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
> 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") } ] |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
> 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. 指定位置来匹配数组
可以使用$操作符在查询中指定的查询匹配的数组项的位置。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
> 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. 获取最近一次更改信息
1 2 3 4 5 6 7 8 9 10 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()
语法:
1 2 3 4 5 6 7 8 9 |
db.collection.findAndModify({ query: <document>, sort: <document>, remove: <boolean>, update: <document>, new: <boolean>, fields: <document>, upsert: <boolean> }); |
原子更新,该命令查询并修改文档。
1 2 3 4 5 6 7 8 9 10 |
> 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() [ ] |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
> 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”并返回旧文档。要返回更改后的文档按下面操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
> 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") } ] |

29/02/2016 下午 6:52 沙发
第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是因为什么?一直解决不了,求教
29/02/2016 下午 8:20 1层
@汪伽 “err” : “Cannot apply $inc modifier to non-number”,只有数字才能使用$inc,留一下你的值类型