以下find
方法应返回符合指定选择条件的任何文档,并且如果按可选参数sort
指定的方式对其进行排序:
class DaoComponent {
...
val toObjectId = (__.json.update((__ \ '_id \ '$oid).json.copyFrom((__ \ 'id).json.pick))
andThen (__ \ 'id).json.prune
)
...
def find(selector: JsValue, sort: Option[JsValue]): Future[Seq[A]] = {
selector.transform(toObjectId).flatMap { s =>
sort.map(_.transform((__ \ 'ignore).json.prune)).map { o =>
// how do I get 'o' to be either None or Some(content of JsSuccess)?
collection.find(s)
.sort(o.getOrElse(Json.obj())
.cursor[JsValue].collect[Vector](0)
}.recoverTotal { errors =>
Future.failed(JsError.toFlatJson(errors))
}
}
}
在上面的代码中,让我们隔离我需要您宝贵支持的行:
sort.map(_.transform((__ \ 'ignore).json.prune)).map { o =>
可选参数sort
必须仅在定义时进行转换...这是通过map
实现的。现在问题是transform
返回JsResult
,我希望o
在定义可选参数Some(jsValue)
时sort
为transform
,None
成功,或transform
失败时sort
或未定义可选参数None
。
或者,在_.transform
失败时获取recoverTotal
,而不是在{{1}}块中处理失败,这将是很好的。
答案 0 :(得分:1)
扩展我的评论 -
我认为flatMap
和转换你的JsResult asOpt
的正确组合将得到你想要的东西:
sort.flatMap(_.transform((__ \ 'ignore).json.prune).asOpt).map { o =>
// Code in here only executed iff sort defined and transform succeeds
...
}
在我的测试中BTW在这种情况下实际上我无法让transform
“失败” - 我认为如果给定的JSON不存在,prune
是非常宽容的。我可以让它像这样适当地失败:
sort.flatMap(_.transform((__ \ 'ignore).json.pick).asOpt).map { o =>