简体   繁体   中英

How to update a document using ReactiveMongo

I get the following list of documents back from MongoDB when I find for "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
  }
]

Now, what I am trying to do here is for a given campaignID I need to find all its versions (revision in my case) and modify the action field to dead of type String. I read the docs and the examples they have is too simple not too helpful in my case. This is what the docs say:

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)

I can't just follow the docs because its easy to create a new BSON document and use it to modify following the BSON structure by hardcoding the exact fields. In my case I need to find the documents first and then modify the action field on the fly because unlike the docs, my action field can have different values.

Here's my code so far which obviously does not compile:

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
  }

This worked for me as an answer to my own question. Thanks @cchantep for helping me out.

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)

If you have a look at the BSON documentation , you can see BSONArray can be used to pass sequence of BSON values.

BSONDocument("action" -> BSONArray("kick", "punch"))

If you have List[T] as values, with T being provided a BSONWriter[_ <: BSONValue, T] , then this list can be converted as BSONArray .

BSONDocument("action" -> List("kick", "punch"))
// as `String` is provided a `BSONWriter`

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM