ReactiveMongo条件更新

时间:2017-06-22 19:30:31

标签: mongodb scala reactivemongo play-reactivemongo

我对如何使用期货基于之前的查询有条件地更新文档感到困惑。

假设我希望仅在该数组的大小小于给定的整数时才将某些值推送到文档中的数组中。

我正在使用此函数获取文档,在获取文档后我正在推动值 - 我无法做的就是有条件地执行此操作。

def joinGroup(actionRequest: GroupRequests.GroupActionRequest): Future[GroupResponse.GroupActionCompleted] = {
//groupisNotFull() is a boolean future
groupIsNotFull(actionRequest.groupId).map(
  shouldUpdate => {
    if(shouldUpdate){
      Logger.info(actionRequest.initiator + " Joining Group: " + actionRequest.groupId)
      val selector = BSONDocument("group.groupid" -> BSONDocument("$eq" -> actionRequest.groupId))
      val modifier = BSONDocument("$push" -> BSONDocument("group.users" -> "test-user"))
      val updateResult = activeGroups.flatMap(_.update(selector, modifier))
        .map(res => {
          GroupActionCompleted(
            actionRequest.groupId,
            actionRequest.initiator,
            GroupConstants.Actions.JOIN,
            res.ok,
            GroupConstants.Messages.JOIN_SUCCESS
          )
        })
        .recover {
          case e: Throwable => GroupActionCompleted(
            actionRequest.groupId,
            actionRequest.initiator, GroupConstants.Actions.JOIN,
            success = false,
            GroupConstants.Messages.JOIN_FAIL
          )
        }
      updateResult
    }
    else {
      val updateResult = Future.successful(
       GroupActionCompleted(
          actionRequest.groupId,
          actionRequest.initiator,
          GroupConstants.Actions.JOIN,
          success = false,
          GroupConstants.Messages.JOIN_FAIL
        ))
      updateResult
    }
  }
)
}

 //returns a Future[Boolean] based on if there is room for another user.
private def groupIsNotFull(groupid: String): Future[Boolean] = {
findGroupByGroupId(groupid)
  .map(group => {
    if (group.isDefined) {
      val fGroup = group.get
      fGroup.group.users.size < fGroup.group.groupInformation.maxUsers
    } else {
      false
    }
  })

}

我很困惑为什么我不能这样做。编译错误是:

错误:类型不匹配;  发现:scala.concurrent.Future [response.group.GroupResponse.GroupActionCompleted]  required:response.group.GroupResponse.GroupActionCompleted

用于if和else分支'updateResult'。

作为一个侧面问题..这是有条件地更新文档的正确方法 - 即查询它,做一些逻辑然后执行另一个查询?

2 个答案:

答案 0 :(得分:1)

好的 - 你需要flatMap第一个Future[Boolean]这样:

groupIsNotFull(actionRequest.groupId).flatMap( ...

使用flatMap,结果将是带有map的Future [T],您将获得Future [Future [T]]。编译器知道你想要返回一个Future [T],所以它期望map返回一个T并且你试图返回一个Future [T] - 所以它会抛出错误。使用flatMap将解决这个问题。

此处有关地图与平面地图的进一步说明:In Scala Akka futures, what is the difference between map and flatMap?

答案 1 :(得分:0)

我认为问题是因为joinGroup2函数返回类型是Future [Response],但是你只在else块中返回一个Response。如果你看一下mapTo [T]函数的签名,它会返回一个Future [T]。

我认为您需要将Response对象包装在Future中。像这样:

else {
  Future { Response(false, ERROR_REASON) }
}

顺便说一句,你有一个拼写错误:Respose - &gt;响应