假设我有以下DB结构我有用户收集
"users": [
{
"_id": "4775222e-8e4f-4f84-8dba-b097291bbd39",
"surname": "Smith",
"forename": "John"
}
]
我有一个job_requests集合,它在1个字段中引用了用户集合,如下所示:
"job_requests": [
{
"_id": "f4bdda3e-0e8d-4e8d-b070-7d01421f5a51",
"description": "do something",
"riskManager": {
"$ref": "users",
"$id": "4775222e-8e4f-4f84-8dba-b097291bbd39"
}
}
]
最后,我有一个jobs集合,它在1个字段中引用了job_requestscollection:
"jobs": [
{
"_id": "someID",
"description": "do something",
"jobRequest": {
"$ref": "job_requests",
"$id": "f4bdda3e-0e8d-4e8d-b070-7d01421f5a51"
}
}
]
我需要一个按userId返回所有作业的查询,这意味着我需要找到该用户的所有job_requests,然后找到这些job_request的所有作业。我在MongoPlayground上尝试了mongo聚合,这很有效,但仅适用于mongo 4.4.1
db.jobs.aggregate([
{
"$lookup": {
"from": "job_requests",
"localField": "jobRequest.$id",
"foreignField": "_id",
"as": "jobRequest"
}
},
{
"$unwind": "$jobRequest"
},
{
"$match": {
"jobRequest.riskManager.$id": "4775222e-8e4f-4f84-8dba-b097291bbd39"
}
}
])
并给出了正确的结果。问题是,我的服务器是4.2.8版本,在该版本上,这会产生错误"FieldPath字段名不能以'$'开头。">如何进行查询,使其不会在4.2.8中断?我无法重组数据,我需要在集合之间建立所有这些关系。我可以补充一点,最上面的后端是spring数据mongodb,所以我可以使用这些功能来构建查询,但我想它可以归结为mongo QL.的javascript
正如本博客文章中所建议的,可以使用$objectToArray、$arrayElemAt和$$addFields运算符来完成。
所以它变成了类似的东西
db.jobs.aggregate([
{
"$addFields": {
"jobRequest": {
"$arrayElemAt": [
{
"$objectToArray": "$jobRequest"
},
1
]
}
}
},
{
"$addFields": {
"jobRequest": "$jobRequest.v"
}
},
{
"$lookup": {
"from": "job_requests",
"localField": "jobRequest",
"foreignField": "_id",
"as": "jobRequest"
}
},
{
"$addFields": {
"jobRequest": {
"$arrayElemAt": [
"$jobRequest",
0
]
}
}
},
{
"$unwind": "$jobRequest"
},
{
"$match": {
"jobRequest.riskManager.$id": "4775222e-8e4f-4f84-8dba-b097291bbd39"
}
}
])
使用mongo时,请不惜一切代价避免使用DbRef。