db.collection.updateOne(filter,update,options)

顾名思义,通过这行声明,我们大概可以猜到这三个参数大概的作用:

  1. filter 用作在更新之前筛选符合条件的document
  2. update 具体更新document中哪些字段
  3. options 附加可选的额外操作

整体updateOne语句的语法如下:

db.collection.updateOne(
   <filter>,
   <update>,
   {
     upsert: <boolean>,   //true的时候如果filter没有匹配到则将update的内容插入到集合collection
     writeConcern: <document>,  //写事物
     collation: <document>,
     arrayFilters: [ <filterdocument1>, ... ],
     hint:  <document|string>        // Available starting in MongoDB 4.2.1
   }
)

案例一:更新某个文档

案例原始数据:

> db.user.find()
{ "_id" : ObjectId("60c20b6adebf968f925b0dde"), "name" : "peng" }
{ "_id" : ObjectId("60c20c98debf968f925b0ddf"), "name" : "jian" }
{ "_id" : ObjectId("60c20cb6debf968f925b0de0"), "name" : "song" }
{ "_id" : ObjectId("60c20e51debf968f925b0de1"), "name" : "song" }

常规操作,该操作原始数据皆基于上方案例的原始数据。

操作 1 -> 当集合中存在多个filter结果相同的文档时,结果为:更新第一个匹配到的文档。
过程:

> db.user.updateOne({"name":"song"},{$set:{"name":"song1"}})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
> db.user.find()
{ "_id" : ObjectId("60c20b6adebf968f925b0dde"), "name" : "peng" }
{ "_id" : ObjectId("60c20c98debf968f925b0ddf"), "name" : "jian" }
{ "_id" : ObjectId("60c20cb6debf968f925b0de0"), "name" : "song1" }//第一个匹配到的被改变
{ "_id" : ObjectId("60c20e51debf968f925b0de1"), "name" : "song" }//第二个没有变化

操作 2 -> 存在upsert为true时,没有匹配到则插入update内容,匹配到则更新。
过程:

> db.user.updateOne({"name":"song1"},{$set:{"name":"song2"}},{upsert:true})
{
	"acknowledged" : true,
	"matchedCount" : 0,
	"modifiedCount" : 0,
	"upsertedId" : ObjectId("60c219b2e8920eaea30fc37b")
}
> db.user.find()
{ "_id" : ObjectId("60c218e4000e18ef6bfb8065"), "name" : "peng" }
{ "_id" : ObjectId("60c218e4000e18ef6bfb8066"), "name" : "jian" }
{ "_id" : ObjectId("60c218e4000e18ef6bfb8067"), "name" : "song" }
{ "_id" : ObjectId("60c218e4000e18ef6bfb8068"), "name" : "song" }
{ "_id" : ObjectId("60c219b2e8920eaea30fc37b"), "name" : "song2" }
> 

案例二:聚合操作

官方案例:

> db.members.find().pretty()
{
	"_id" : 1,
	"member" : "abc123",
	"status" : "A",
	"points" : 2,
	"misc1" : "note to self: confirm status",
	"misc2" : "Need to activate",
	"lastUpdate" : ISODate("2019-01-01T00:00:00Z")
}
{
	"_id" : 2,
	"member" : "xyz123",
	"status" : "A",
	"points" : 60,
	"comments" : [
		"reminder: ping me at 100pts",
		"Some random comment"
	],
	"lastUpdate" : ISODate("2019-01-01T00:00:00Z")
}

操作要求:

假设你不想在第一个文档中的misc1和misc2字段单独存放,而是希望将它们收集到一个comments字段中,就像第二个文档一样。这些想法可以使用下面的聚合管道来完成。

该操作分为两步:

  1. 添加一个新的comments带有misc1根misc2内容的字段到文档一中,并更新lastUpdate字段时间
  2. 删除misc1和misc2字段

过程:

db.members.updateOne(
   { _id: 1 },
   [
      { $set: { status: "Modified", comments: [ "$misc1", "$misc2" ], lastUpdate: "$$NOW" } },
      { $unset: [ "misc1", "misc2" ] }
   ]
)

具有一个“ $ ” 符号,表示引用当前匹配文档中的字段,“ NOW ” 表示获取当前系统的时间(UTC时间,比我们的时间少8个小时)是聚合变量,要通过它获取时间值需要前面加两个美元符号$$并且用双引号括起来。

管道中使用的“set”和 u n s e t 分 别 引 用 聚 合 阶 段 unset分别引用聚合阶段 unsetset和 u n s e t , 而 不 是 u p d a t e 操 作 符 unset,而不是update操作符 unsetupdateset和$unset。
unset可以用来删除文档中的字段。

未完待续!

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐