3

1 つのフィールドがリストである mongo エントリがあります。エントリが存在しない場合は、新しいものを追加したい。存在する場合は、新しい要素をリストに追加します。

最後に、クライアントに Ok を返したいのですが、操作が正常に完了した後でのみです。厳密な要件ではありませんが、ユーザーにとって最も理にかなっていると思います。

これは私が現在持っているものです-動作しますが、更新すると、新しい要素を追加する代わりに、古いリストが上書きされます。

def myMethod(value:String, value2:String) = Action {

  Async {
    val myElement = Json.obj(
      "key" -> value2
    )

    val myDBEntry = Json.obj(
      "key" -> value,
      "list" -> List(myElement)
    )

    collection.update(Json.obj("key" -> value), myDBEntry, upsert = true).map(lastError =>
      Ok("Mongo LastError: %s".format(lastError)))
  }
}

リストが存在するかどうかを確認し、要素を追加して新しいリストを作成するために、次のようなものから始めました (これはcollection.update前のコードのブロックを置き換えます)。

val futureResult:Future[Option[JsObject]] = collection.find(Json.obj("key" -> value)).one[JsObject]

futureResult.map { result =>

  if (result.isEmpty) {
      collection.insert(myDBEntry).map(lastError =>
        Ok("Mongo LastError: %s".format(lastError)))


  } else {
      //this not the correct command yet - but compiler already fails because method is not returning correct future 
      collection.update(Json.obj("key" -> value), myDBEntry, upsert = true).map(lastError =>
        Ok("Mongo LastError: %s".format(lastError)))
  }


}

しかし、コンパイラはこの入れ子を好まないようです:

とにかく、この方法は少しぎこちなく感じます。これを解決するためのよりエレガントな方法があるはずですが、私は Futures と ReactiveMongo が初めてで、わかりません。どうすれば解決できますか?

編集: 私もこの投稿を見つけましたが、DB 操作が完了する前に応答を返していると思いますが、それは望ましくありません。

4

1 に答える 1