如何使用 ReactiveMongo 更新文档
How to update a document using ReactiveMongo
当我找到 "campaignID":"DEMO-1"
.
时,我从 MongoDB 得到了以下文档列表
[
{
"_id": {
"$oid": "56be0e8b3cf8a2d4f87ddb97"
},
"campaignID": "DEMO-1",
"revision": 1,
"action": [
"kick",
"punch"
],
"transactionID": 20160212095539543
},
{
"_id": {
"$oid": "56c178215886447ea261710f"
},
"transactionID": 20160215000257159,
"campaignID": "DEMO-1",
"revision": 2,
"action": [
"kick"
],
"transactionID": 20160212095539578
}
]
现在,我在这里要做的是针对给定的 campaignID
我需要找到它的所有版本(在我的例子中是修订版)并将 action
字段修改为 dead
类型的字符串。我阅读了文档,他们提供的示例太简单了,对我来说帮助不大。文档是这样说的:
val selector = BSONDocument("name" -> "Jack")
val modifier = BSONDocument(
"$set" -> BSONDocument(
"lastName" -> "London",
"firstName" -> "Jack"),
"$unset" -> BSONDocument(
"name" -> 1))
// get a future update
val futureUpdate = collection.update(selector, modifier)
我不能只关注文档,因为创建新的 BSON 文档并使用它通过对确切字段进行硬编码来修改 BSON 结构很容易。在我的例子中,我需要先找到文档,然后即时修改 action
字段,因为与文档不同,我的 action
字段可以有不同的值。
到目前为止,这是我的代码,但显然无法编译:
def updateDocument(campaignID: String) ={
val timeout = scala.concurrent.duration.Duration(5, "seconds")
val collection = db.collection[BSONCollection](collectionName)
val selector = BSONDocument("action" -> "dead")
val modifier = collection.find(BSONDocument("campaignID" -> campaignID)).cursor[BSONDocument]().collect[List]()
val updatedResults = Await.result(modifier, timeout)
val mod = BSONDocument(
"$set" -> updatedResults(0),
"$unset" -> BSONDocument(
"action" -> **<???>** ))
val futureUpdate = collection.update(selector, updatedResults(0))
futureUpdate
}
如果您查看 BSON documentation,您会发现 BSONArray
可用于传递 BSON 值序列。
BSONDocument("action" -> BSONArray("kick", "punch"))
如果您将 List[T]
作为值,并为 T
提供 BSONWriter[_ <: BSONValue, T]
,则此列表可以转换为 BSONArray
。
BSONDocument("action" -> List("kick", "punch"))
// as `String` is provided a `BSONWriter`
这对我有用,可以回答我自己的问题。感谢@cchantep 帮助我。
val collection = db.collection[BSONCollection](collectionName)
val selector = BSONDocument("campaignID" -> campaignID)
val mod = BSONDocument("$set" -> BSONDocument("action" -> "dead"))
val futureUpdate = collection.update(selector, mod, multi = true)
当我找到 "campaignID":"DEMO-1"
.
[
{
"_id": {
"$oid": "56be0e8b3cf8a2d4f87ddb97"
},
"campaignID": "DEMO-1",
"revision": 1,
"action": [
"kick",
"punch"
],
"transactionID": 20160212095539543
},
{
"_id": {
"$oid": "56c178215886447ea261710f"
},
"transactionID": 20160215000257159,
"campaignID": "DEMO-1",
"revision": 2,
"action": [
"kick"
],
"transactionID": 20160212095539578
}
]
现在,我在这里要做的是针对给定的 campaignID
我需要找到它的所有版本(在我的例子中是修订版)并将 action
字段修改为 dead
类型的字符串。我阅读了文档,他们提供的示例太简单了,对我来说帮助不大。文档是这样说的:
val selector = BSONDocument("name" -> "Jack")
val modifier = BSONDocument(
"$set" -> BSONDocument(
"lastName" -> "London",
"firstName" -> "Jack"),
"$unset" -> BSONDocument(
"name" -> 1))
// get a future update
val futureUpdate = collection.update(selector, modifier)
我不能只关注文档,因为创建新的 BSON 文档并使用它通过对确切字段进行硬编码来修改 BSON 结构很容易。在我的例子中,我需要先找到文档,然后即时修改 action
字段,因为与文档不同,我的 action
字段可以有不同的值。
到目前为止,这是我的代码,但显然无法编译:
def updateDocument(campaignID: String) ={
val timeout = scala.concurrent.duration.Duration(5, "seconds")
val collection = db.collection[BSONCollection](collectionName)
val selector = BSONDocument("action" -> "dead")
val modifier = collection.find(BSONDocument("campaignID" -> campaignID)).cursor[BSONDocument]().collect[List]()
val updatedResults = Await.result(modifier, timeout)
val mod = BSONDocument(
"$set" -> updatedResults(0),
"$unset" -> BSONDocument(
"action" -> **<???>** ))
val futureUpdate = collection.update(selector, updatedResults(0))
futureUpdate
}
如果您查看 BSON documentation,您会发现 BSONArray
可用于传递 BSON 值序列。
BSONDocument("action" -> BSONArray("kick", "punch"))
如果您将 List[T]
作为值,并为 T
提供 BSONWriter[_ <: BSONValue, T]
,则此列表可以转换为 BSONArray
。
BSONDocument("action" -> List("kick", "punch"))
// as `String` is provided a `BSONWriter`
这对我有用,可以回答我自己的问题。感谢@cchantep 帮助我。
val collection = db.collection[BSONCollection](collectionName)
val selector = BSONDocument("campaignID" -> campaignID)
val mod = BSONDocument("$set" -> BSONDocument("action" -> "dead"))
val futureUpdate = collection.update(selector, mod, multi = true)