2

Futures と ReactiveMongo を学ぼうとしています。私の場合、いくつかの招待オブジェクトがあり、データベースに既に存在するものを除外したいと考えています。すでにデータベースにあるものを更新またはアップサートしたくありません。したがって、フィルターメソッドを作成しました:

フィルター方法:

def isAllowedToReview(invite: Invite): Future[Boolean] = {
    ReviewDAO.findById(invite.recoId, invite.invitedUserId).map {
      maybeReview => {
        maybeReview match {
          case Some(review) => false
          case None => true
        }
      }
    }
  }

ダオ:

def findById(rId: Long, userId: Long): Future[Option[Review]] = findOne(Json.obj("rId" -> recoId, "userId" -> userId))

def findOne(query: JsObject)(implicit reader: Reads[T]): Future[Option[T]] = {    
   collection.find(query).one[T]
}

そして、次のように呼び出します。

val futureOptionSet: Set[Future[Option[Invite]]] = smsSet.filter(isAllowedToReview)
save the filtered set somehow...

この場合、フィルターInvite => Booleanが期待しているため、これは機能しませんが、送信してInvite => Future(Boolean)います。これをどのようにフィルタリングして保存しますか?

4

2 に答える 2

3

smsSet.map(sms => isAllowedToReview(sms).map(b => sms -> b))タイプがありSet[Future[(Invite, Boolean)]]ます。Future.sequenceに変換するために呼び出すことができるはずですFuture[Set[(Invite, Boolean)]]。その後、結果を収集できます.map(_.collect{ case (sms, true) => sms})

したがって、すべてをまとめたソリューションは次のようになります。

val futures = smsSet.map(sms => isAllowedToReview(sms).map(b => sms -> b))
val future = Future.sequence(futures)
val result = future.map(_.collect{ case (sms, true) => sms})

次のようにリファクタリングできる場合がmapあります。sequence

val filteredSet = Future.traverse(smsSet){ sms => 
  isAllowedToReview(sms).map(b => sms -> b)
}.map(_.collect{ case (sms, true) => sms})

セットを返す代わりに、そこに SMS を保存したい場合があることに注意してください。しかし、私がこれを書いた方法では、すべてが a でラップされ、Future他の操作で構成することができます。

于 2013-06-04T13:31:50.130 に答える
1

次のようなことを試すことができます:

val revsFut = Future.sequence(smsSet.map(invite => ReviewDAO.findById(invite.recoId, invite.invitedUserId)))    
val toSave = for(revs <- revsFut) yield {
  val flatRevs = revs.flatten
  smsSet.filter{ invite =>
    flatRevs.find(review => /*Add filter code here */).isDefined
  }
}

ここで行っているのは、最初に smsSet をマッピングして招待に一致するレビューのセットをフェッチし、それぞれを個別にフェッチしてから、それを 1 つの singe にシーケンス化することFutureです。次に、for-comprehension で of をフラット化しSet、そのSetの内容に基づいて をOption[Review]フィルター処理します。オブジェクトモデルがわからないので、実装はお任せしましたが、そこまでは簡単なはずです。smsSetflatRevsflatRevs.find

于 2013-06-04T13:31:39.803 に答える