如何解决如何在ReactiveMongo聚合框架中使用$ lookup指定多个加入条件?
如何在ReactiveMongo(0.17.1)中使用$ lookup指定多个联接条件,并牢记以下几点? -按照the mongoDB documentation。
用户集合
[
{
"name": "dogfrey","field": "cowboy"
},{
"name": "catsville","field": "spaceman"
}
]
角色收集
[
{
"id": 0,"userType": "cowboy","spaceman": "fiver","num": 2
},{
"id": 1,"userType": "joker","spaceman": "tenner","num": 3
},{
"id": 2,"num": 1
}
]
MongoDb查询
db.users.aggregate([
{
"$match": {
"name": "dogfrey"
}
},{
"$lookup": {
"from": "roles",let: {
"users_field": "$field"
},pipeline: [
{
$match: {
$expr: {
$eq: [
"$userType","$$users_field"
]
},}
},{
$project: {
_id: 0
}
}
],"as": "dogs"
}
}
])
See here for the MongoPlayground example
ReactiveMongo documentation没有包含任何这样的示例,表明不可能。任何帮助表示赞赏!
也只是添加我尝试过的内容(失败):
def getResults(aColl: JSONCollection,bColl: JSONCollection)
(id: BSONObjectID)(implicit request: Request[AnyContent]) = aColl.aggregateWith[JsObject]() {
framework => import framework.{Match,Lookup,AddFields,Project,Sort,Ascending,Descending,Filter,Limit,Group,Sum,Push,Slice}
...
val lookupJso = Lookup(
from = bColl.name,let = Json.obj("fromDate" -> "$varData_e.plan_e.when_e.fromDate","toDate" -> "$varData_e.plan_e.when_e.toDate"),pipeline = Json.arr(
"$match" -> Json.obj("$expr" ->
Json.obj("$and" -> Json.arr(
Json.obj("$gte" -> Json.arr("$varData_e.dateTime",f"$$fromDate")),Json.obj("$lt" -> Json.arr("$varData_e.dateTime",f"$$toDate"))
)),),"$project" -> Json.obj("_id" -> 0)
),"temp_e.lookupTest1_e"
)
...
}.collect[List](Int.MaxValue,Cursor.FailOnError[List[JsObject]]())
我可以看到Lookup case class
看起来像这样:
case class Lookup(
from: String,localField: String,foreignField: String,as: String) extends PipelineOperator {
import builder.{ document,elementProducer => element,string }
val makePipe: pack.Document = document(Seq(
element(f"$$lookup",document(Seq(
element("from",string(from)),element("localField",string(localField)),element("foreignField",string(foreignField)),element("as",string(as)))))))
}
解决方法
版本0.17.1已有一年以上的历史(最新版本为major 1.0)。
您可以在documentation中看到,可以为API中未提供便捷工厂的阶段定义原始聚合运算符。
import scala.concurrent.ExecutionContext
import reactivemongo.bson._
import reactivemongo.api.collections.bson.BSONCollection
def customAgg(coll: BSONCollection)(implicit ec: ExecutionContext) =
coll.aggregateWith[BSONDocument]() { framework =>
import framework.{ Match,PipelineOperator,Project }
val lookup = PipelineOperator(BSONDocument(f"$$lookup" -> BSONDocument(
"from" -> "roles","let" -> BSONDocument("users_field" -> f"$$field"),"pipeline" -> Seq(
Match(BSONDocument(f"$$expr" ->
BSONDocument(f"$$eq" -> Seq(f"$$userType",f"$$$$users_field")))).
makePipe,Project(BSONDocument("_id" -> 0)).makePipe),"as" -> "dogs")))
Match(BSONDocument("name" -> "dogfrey")) -> List(lookup)
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。