Mongodb ReactiveMongo条件更新
我不知道如何根据以前的查询,仅使用futures有条件地更新文档 假设我只想在一个数组的大小小于给定整数的情况下,将某个值推送到文档中的数组中 我使用这个函数来获取文档,在获取文档后我推送值-我不能做的是有条件地这样做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
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块更好的模式。