Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mongodb ReactiveMongo条件更新_Mongodb_Scala_Reactivemongo_Play Reactivemongo - Fatal编程技术网

Mongodb ReactiveMongo条件更新

Mongodb ReactiveMongo条件更新,mongodb,scala,reactivemongo,play-reactivemongo,Mongodb,Scala,Reactivemongo,Play Reactivemongo,我不知道如何根据以前的查询,仅使用futures有条件地更新文档 假设我只想在一个数组的大小小于给定整数的情况下,将某个值推送到文档中的数组中 我使用这个函数来获取文档,在获取文档后我推送值-我不能做的是有条件地这样做 def joinGroup(actionRequest: GroupRequests.GroupActionRequest): Future[GroupResponse.GroupActionCompleted] = { //groupisNotFull() is a boole

我不知道如何根据以前的查询,仅使用futures有条件地更新文档

假设我只想在一个数组的大小小于给定整数的情况下,将某个值推送到文档中的数组中

我使用这个函数来获取文档,在获取文档后我推送值-我不能做的是有条件地这样做

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
    }
  })
def joinGroup(actionRequest:GroupRequests.GroupActionRequest):未来[GroupResponse.GroupActionCompleted]={
//groupisNotFull()是一个布尔值
groupIsNotFull(actionRequest.groupId).map(
shouldUpdate=>{
如果(应该更新){
Logger.info(actionRequest.initiator+“加入组:”+actionRequest.groupId)
val选择器=BSONDocument(“group.groupid”->BSONDocument($eq”->actionRequest.groupid))
val修饰符=BSONDocument($push->BSONDocument(“group.users”->“test user”))
val updateResult=activeGroups.flatMap(u.update(选择器、修饰符))
.map(res=>{
组操作已完成(
actionRequest.groupId,
actionRequest.initiator,
GroupConstants.Actions.JOIN,
好的,
GroupConstants.Messages.JOIN_成功
)
})
.恢复{
案例e:Throwable=>GroupActionCompleted(
actionRequest.groupId,
actionRequest.initiator,GroupConstants.Actions.JOIN,
成功=错误,
GroupConstants.Messages.JOIN\u失败
)
}
更新结果
}
否则{
val updateResult=Future.successful(
组操作已完成(
actionRequest.groupId,
actionRequest.initiator,
GroupConstants.Actions.JOIN,
成功=错误,
GroupConstants.Messages.JOIN\u失败
))
更新结果
}
}
)
}
//根据是否有其他用户的空间返回未来的[Boolean]。
private def groupIsNotFull(groupid:String):Future[Boolean]={
findGroupByGroupId(groupid)
.map(组=>{
如果(已定义组){
val fGroup=group.get
fGroup.group.users.size
}

我不明白为什么我不能这样做。编译错误是:

错误:类型不匹配; 找到:scala.concurrent.Future[response.group.GroupResponse.GroupActionCompleted] 必需:response.group.GroupResponse.GroupActionCompleted

对于if和else分支“updateResult”


作为一个附带问题。。这是有条件地更新文档的正确方法吗?即查询文档,执行一些逻辑,然后执行另一个查询?

我认为问题在于joinGroup2函数返回类型是Future[Response],而您只返回else块中的响应。如果查看mapTo[T]函数的签名,它将返回未来的[T]

我认为您需要在将来包装响应对象。大概是这样的:

else {
  Future { Response(false, ERROR_REASON) }
}
groupIsNotFull(actionRequest.groupId).flatMap( ...

顺便说一句,您有一个输入错误:Respose->Response

好了-您需要
flatMap
第一个
Future[Boolean]
如下:

else {
  Future { Response(false, ERROR_REASON) }
}
groupIsNotFull(actionRequest.groupId).flatMap( ...
使用
flatMap
,结果将是一个未来[T],使用
map
您将得到一个未来[T]。编译器知道您想要返回一个未来的[T],因此它期望映射返回一个T,而您正试图返回一个未来的[T]——因此它抛出错误。使用flatMap可以解决这个问题


这里对map与flatmap做了进一步的澄清:

未来。成功的
纯值包装在未来仍然会给我一个错误:错误类型不匹配;find:scala.concurrent.Future[response.response]required:response.response我想这是因为if语句中有第二个映射函数和嵌套的Future,我对如何在这种情况下使用flatMap有点不确定您是否尝试了Future.successful(response(false,“FAILURE”))?我正在用一个不太做作的例子和我正在使用的实际代码更新问题。为什么不看看
find和modify
?@cchantep据我所知,我不能在查询本身内进行条件更新。这是在阅读mongodb文档后设计的,业务逻辑应该在查询之外。这取决于您所说的条件,
findAndModify
允许更新或删除与查询匹配的现有文档。@cchantep ok,也许我会看看是否有一些查询我可以做,返回文档与一个给定的字段与一个size@cchantep我认为一个更好的解决方案是添加一个新字段作为计数器,而不是基于该字段的大小查询。非常感谢,但是我最终选择了另一种方法来有条件地更新它。我在文档中添加了一个字段,该字段在每次添加数组时都会递减。然后查询将选择与id和该字段值>0匹配的文档。没问题。但是,由于您希望有选择地返回文档,因此返回未来的[选项[文档]]可能更“实用”。即,如果有文档,则返回一些(文档),如果文档小于大小阈值,则返回无文档。这可能是比if/else块更好的模式。