Как обновить документ с помощью ReactiveMongo

Я получаю следующий список документов из MongoDB, когда нахожу "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 типа String. Я прочитал документы, и примеры, которые у них есть, слишком просты, не слишком полезны в моем случае. Вот что говорят документы:

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
  }

person summerNight    schedule 18.02.2016    source источник
comment
Я думаю, что запутался между селектором и модификатором. Я думаю, что мой селектор должен быть "action" -> "[ "kick", "punch" ]", что синтаксически неверно, но я не уверен, как передать список. Также в примере, почему имя было установлено снова, так как оно уже было установлено на Джек   -  person summerNight    schedule 19.02.2016


Ответы (2)


Это сработало для меня как ответ на мой собственный вопрос. Спасибо @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)
person summerNight    schedule 19.02.2016
comment
Я не понимаю минус. Я разместил вопрос и предоставил ответ, который фактически исправил то, что я хотел исправить. Это может помочь кому-то с похожими проблемами. - person summerNight; 19.02.2016

Если вы посмотрите на документацию BSON, вы увидите, что 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`
person cchantep    schedule 18.02.2016