mongodb更新数据可以使用updateOne()、updateMany()以及replaceOne()等方法。这些方法一般需要配合update operator使用,了解update operator参考Update Operators。文中使用的脚本文件可以从百度云下载:mongodb_query_language
连接mongodb数据库
在进行下面的操作前需要先使用mongo shell连接mongodb数据库,参考启动mongod并使用mongo shell连接。
插入数据
更新操作之前需要先插入数据,执行下面的命令插入数据:
load("/Users/chenxin/Downloads/mongodb_query_language/loadMovieDetailsDataset/loadMovieDetailsDataset.js")
注意需要把load中js文件路径修改为自己机器上的路径。插入数据更多细节可以参考mongo shell执行javascript文件。
updateOne()
updateOne()方法只能更新一个document,如果匹配到多个document,只会更新第一个。首先执行db.movieDetails.find({ "title": "The Martian"}).pretty()
查看一个数据:
{
"_id" : ObjectId("5b4469e5f08b7fb5d9736de6"),
"title" : "The Martian",
"year" : 2015,
"rated" : "PG-13",
"runtime" : 144,
"countries" : [
"USA",
"UK"
],
"genres" : [
"Adventure",
"Drama",
"Sci-Fi"
],
"director" : "Ridley Scott",
"writers" : [
"Drew Goddard",
"Andy Weir"
],
"actors" : [
"Matt Damon",
"Jessica Chastain",
"Kristen Wiig",
"Jeff Daniels"
],
"plot" : "During a manned mission to Mars, Astronaut Mark Watney is presumed dead after a fierce storm and left behind by his crew. But Watney has survived and finds himself stranded and alone on the hostile planet. With only meager supplies, he must draw upon his ingenuity, wit and spirit to subsist and find a way to signal to Earth that he is alive.",
"imdb" : {
"id" : "tt3659388",
"rating" : 8.2,
"votes" : 187881
},
"tomato" : {
"meter" : 93,
"image" : "certified",
"rating" : 7.9,
"reviews" : 280,
"fresh" : 261,
"consensus" : "Smart, thrilling, and surprisingly funny, The Martian offers a faithful adaptation of the bestselling book that brings out the best in leading man Matt Damon and director Ridley Scott.",
"userMeter" : 92,
"userRating" : 4.3,
"userReviews" : 104999
},
"metacritic" : 80,
"type" : "movie"
}
可以看到title
为The Martian
的document只有一个,并且它没有poster
字段。现在修改它的poster
字段,执行下面的命令:
db.movieDetails.updateOne( { "title": "The Martian"}, {$set: {"poster": "https://www.baidu.com"}})
终端输出
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
可以看到修改成功,执行db.movieDetails.find({ "title": "The Martian"}).pretty()
重新查看数据:
{
"_id" : ObjectId("5b4469e5f08b7fb5d9736de6"),
"title" : "The Martian",
"year" : 2015,
"rated" : "PG-13",
"runtime" : 144,
"countries" : [
"USA",
"UK"
],
"genres" : [
"Adventure",
"Drama",
"Sci-Fi"
],
"director" : "Ridley Scott",
"writers" : [
"Drew Goddard",
"Andy Weir"
],
"actors" : [
"Matt Damon",
"Jessica Chastain",
"Kristen Wiig",
"Jeff Daniels"
],
"plot" : "During a manned mission to Mars, Astronaut Mark Watney is presumed dead after a fierce storm and left behind by his crew. But Watney has survived and finds himself stranded and alone on the hostile planet. With only meager supplies, he must draw upon his ingenuity, wit and spirit to subsist and find a way to signal to Earth that he is alive.",
"imdb" : {
"id" : "tt3659388",
"rating" : 8.2,
"votes" : 187881
},
"tomato" : {
"meter" : 93,
"image" : "certified",
"rating" : 7.9,
"reviews" : 280,
"fresh" : 261,
"consensus" : "Smart, thrilling, and surprisingly funny, The Martian offers a faithful adaptation of the bestselling book that brings out the best in leading man Matt Damon and director Ridley Scott.",
"userMeter" : 92,
"userRating" : 4.3,
"userReviews" : 104999
},
"metacritic" : 80,
"type" : "movie",
"poster" : "https://www.baidu.com"
}
可以看到最后一行多了poster
字段。updateOne()更新字段时,如果字段已经存在,会修改字段的值,如果字段不存在,会新建字段并修改为指定的值。
updateMany()
执行命令db.movieDetails.find({ "rated": null})
查看rated
字段值为null
的document:
{ "_id" : ObjectId("5b4469e5f08b7fb5d9736515"), "title" : "Turks in Space", "year" : 2006, "rated" : null, "runtime" : 110, "countries" : [ "Turkey" ], "genres" : [ "Action", "Comedy", "Sci-Fi" ], "director" : "Kartal Tibet", "writers" : [ "Murat Boyacioglu" ], "actors" : [ "Cüneyt Arkin", "Haldun Boysan", "Berda Ceyhan", "Veysel Diker" ], "plot" : "A family of Turks try to adapt to life in a new solar system.", "poster" : "http://ia.media-imdb.com/images/M/MV5BMTYwOTMwODIxNF5BMl5BanBnXkFtZTcwMjc0NzA0MQ@@._V1_SX300.jpg", "imdb" : { "id" : "tt0808240", "rating" : 1.9, "votes" : 12638 }, "awards" : { "wins" : 0, "nominations" : 0, "text" : "" }, "type" : "movie" }
......
{ "_id" : ObjectId("5b4469e5f08b7fb5d97365db"), "title" : "A Cruel Romance", "year" : 1984, "rated" : null, "runtime" : 142, "countries" : [ "Soviet Union" ], "genres" : [ "Drama", "Romance" ], "director" : "Eldar Ryazanov", "writers" : [ "Aleksandr Ostrovskiy", "Eldar Ryazanov" ], "actors" : [ "Alisa Freyndlikh", "Larisa Guzeeva", "Nikita Mikhalkov", "Andrey Myagkov" ], "plot" : "Cinematographic adaptation of classical Russian play \"Dowry-less\" by A. Ostrovsky. Noble but poor widow seeks to arrange marriage for her three daughters. She maintains \"open house\" or ...", "poster" : "http://ia.media-imdb.com/images/M/MV5BNDY4NDMwMDI2Nl5BMl5BanBnXkFtZTcwMjE2ODAwMQ@@._V1_SX300.jpg", "imdb" : { "id" : "tt0090368", "rating" : 8.1, "votes" : 2153 }, "awards" : { "wins" : 0, "nominations" : 0, "text" : "" }, "type" : "movie" }
Type "it" for more
可以看到这样的记录很多。现在要求任意一个document,如果rated
字段值为null
,则移除该字段,可以执行下面的命令:
db.movieDetails.updateMany( { "rated": null }, {$unset: { "rated": "" }})
这个命令使用了unset
操纵符,终端输出
{ "acknowledged" : true, "matchedCount" : 1599, "modifiedCount" : 1599 }
可以看到共修改了1599个document。重新执行命令db.movieDetails.find({ "rated": null})
查看rated
字段值为null
的document:
{ "_id" : ObjectId("5b4469e5f08b7fb5d9736515"), "title" : "Turks in Space", "year" : 2006, "runtime" : 110, "countries" : [ "Turkey" ], "genres" : [ "Action", "Comedy", "Sci-Fi" ], "director" : "Kartal Tibet", "writers" : [ "Murat Boyacioglu" ], "actors" : [ "Cüneyt Arkin", "Haldun Boysan", "Berda Ceyhan", "Veysel Diker" ], "plot" : "A family of Turks try to adapt to life in a new solar system.", "poster" : "http://ia.media-imdb.com/images/M/MV5BMTYwOTMwODIxNF5BMl5BanBnXkFtZTcwMjc0NzA0MQ@@._V1_SX300.jpg", "imdb" : { "id" : "tt0808240", "rating" : 1.9, "votes" : 12638 }, "awards" : { "wins" : 0, "nominations" : 0, "text" : "" }, "type" : "movie" }
......
{ "_id" : ObjectId("5b4469e5f08b7fb5d97365db"), "title" : "A Cruel Romance", "year" : 1984, "runtime" : 142, "countries" : [ "Soviet Union" ], "genres" : [ "Drama", "Romance" ], "director" : "Eldar Ryazanov", "writers" : [ "Aleksandr Ostrovskiy", "Eldar Ryazanov" ], "actors" : [ "Alisa Freyndlikh", "Larisa Guzeeva", "Nikita Mikhalkov", "Andrey Myagkov" ], "plot" : "Cinematographic adaptation of classical Russian play \"Dowry-less\" by A. Ostrovsky. Noble but poor widow seeks to arrange marriage for her three daughters. She maintains \"open house\" or ...", "poster" : "http://ia.media-imdb.com/images/M/MV5BNDY4NDMwMDI2Nl5BMl5BanBnXkFtZTcwMjE2ODAwMQ@@._V1_SX300.jpg", "imdb" : { "id" : "tt0090368", "rating" : 8.1, "votes" : 2153 }, "awards" : { "wins" : 0, "nominations" : 0, "text" : "" }, "type" : "movie" }
Type "it" for more
可以看到还是刚才的记录,但是rated
字段都不存在了。既然不存在为什么会被过滤出来呢?显然对于不存在的字段,它的值默认为null
网友评论