MongoDB 使用管道查找嵌套连接
MongoDB lookup with pipeline for nested joins
我有两个集合,我正在对其执行查找以获取组合数据。
公司:
{
"_id": "638760ea-d109-49fd-8447-b52fe39227a3",
"company": "test",
"phones": [
{
"iso": "in",
"number": "54666",
"label": "CF_61a8c36b3368b0b21dbfbe3d"
},
{
"iso": "hu",
"number": "54433",
"label": "CF_61a8c37d3368b0b21dbfbe3e"
}
]
}
联系人标签:
{
"_id": "096b0446-1099-49f4-87fc-21e583581780",
"values": [
{
"id": "0a5c3f36-a06d-4f34-a1a9-9bbef7370940",
"code": "CF_61a8c36b3368b0b21dbfbe3d",
"value": "Personal"
},
{
"id": "693574f9-cb30-48b1-9394-7673c9e71f33",
"code": "CF_61a8c37d3368b0b21dbfbe3e",
"value": "Home"
}
]
}
我想要输出为
{
"_id": "638760ea-d109-49fd-8447-b52fe39227a3",
"company": "test",
"phones": [
{
"iso": "in",
"number": "54666",
"label": "CF_61a8c36b3368b0b21dbfbe3d",
"value": "Personal"
},
{
"iso": "hu",
"number": "54433",
"label": "CF_61a8c37d3368b0b21dbfbe3e",
"value": "Home"
}
]
}
这是我为获得结果而应用的查询
{
from: 'ContactLables',
let:'ContactLablesCode':'$values.code',
pipeline: [
{ "$match": {
"$expr": { "$eq": [ "$phones.label", "$$ContactLablesCode" ] }
}}
],
as: 'phoneLables'
}
以上查询没有给我任何结果,对此有什么建议吗?
查询 1
- 放松 phones
- 使用管道查找但版本 MongoDB 5
我们有 localfield/foreighfield + 管道
localfield= the phones.label
和 foreign=array with the codes
- if match => 数组有我们想要的标签,但我们不知道是哪个成员
- 展开并匹配以仅保留
phone.label
的值,例如“Home”
- 现在每个 phone 我们从另一个集合中得到它的值
- 用 set/unset 修复结构(1 组和
"$$REMOVE"
也可以)
- 最后分组并将 phone 推送给
_id
所有者
*为了加快速度,您需要 ContactLables.value
和 MongoDB 5 上的多键索引(此处查询是为了让 MongoDB 5 更快并使用 idenx)
Company.aggregate(
[{"$unwind":"$phones"},
{"$lookup":
{"from":"ContactLables",
"localField":"phones.label",
"foreignField":"values.code",
"pipeline":
[{"$unwind":"$values"},
{"$match":{"$expr":{"$eq":["$values.code", "$$label"]}}},
{"$project":{"_id":0, "value":"$values.value"}}],
"as":"results",
"let":{"label":"$phones.label"}}},
{"$set":{"phones.value":{"$first":"$results.value"}}},
{"$unset":["results"]},
{"$group":
{"_id":"$_id",
"company":{"$first":"$company"},
"phones":{"$push":"$phones"}}}])
查询2
- 同上,但管道内部使用reduce代替unwind和match
- reduce 以查找匹配的成员,并保留其值,例如“Home”
Company.aggregate(
[{"$unwind":"$phones"},
{"$lookup":
{"from":"ContactLables",
"localField":"phones.label",
"foreignField":"values.code",
"pipeline":
[{"$project":
{"_id":0,
"value":
{"$reduce":
{"input":"$values",
"initialValue":null,
"in":
{"$let":
{"vars":{"v":"$$value"},
"in":
{"$cond":
[{"$eq":["$$this.code", "$$label"]}, "$$this.value",
"$$v"]}}}}}}}],
"as":"results",
"let":{"label":"$phones.label"}}},
{"$set":{"phones.value":{"$first":"$results.value"}}},
{"$unset":["results"]},
{"$group":
{"_id":"$_id",
"company":{"$first":"$company"},
"phones":{"$push":"$phones"}}}])
我有两个集合,我正在对其执行查找以获取组合数据。
公司:
{
"_id": "638760ea-d109-49fd-8447-b52fe39227a3",
"company": "test",
"phones": [
{
"iso": "in",
"number": "54666",
"label": "CF_61a8c36b3368b0b21dbfbe3d"
},
{
"iso": "hu",
"number": "54433",
"label": "CF_61a8c37d3368b0b21dbfbe3e"
}
]
}
联系人标签:
{
"_id": "096b0446-1099-49f4-87fc-21e583581780",
"values": [
{
"id": "0a5c3f36-a06d-4f34-a1a9-9bbef7370940",
"code": "CF_61a8c36b3368b0b21dbfbe3d",
"value": "Personal"
},
{
"id": "693574f9-cb30-48b1-9394-7673c9e71f33",
"code": "CF_61a8c37d3368b0b21dbfbe3e",
"value": "Home"
}
]
}
我想要输出为
{
"_id": "638760ea-d109-49fd-8447-b52fe39227a3",
"company": "test",
"phones": [
{
"iso": "in",
"number": "54666",
"label": "CF_61a8c36b3368b0b21dbfbe3d",
"value": "Personal"
},
{
"iso": "hu",
"number": "54433",
"label": "CF_61a8c37d3368b0b21dbfbe3e",
"value": "Home"
}
]
}
这是我为获得结果而应用的查询
{
from: 'ContactLables',
let:'ContactLablesCode':'$values.code',
pipeline: [
{ "$match": {
"$expr": { "$eq": [ "$phones.label", "$$ContactLablesCode" ] }
}}
],
as: 'phoneLables'
}
以上查询没有给我任何结果,对此有什么建议吗?
查询 1
- 放松 phones
- 使用管道查找但版本 MongoDB 5 我们有 localfield/foreighfield + 管道
localfield= the phones.label
和foreign=array with the codes
- if match => 数组有我们想要的标签,但我们不知道是哪个成员
- 展开并匹配以仅保留
phone.label
的值,例如“Home” - 现在每个 phone 我们从另一个集合中得到它的值
- 用 set/unset 修复结构(1 组和
"$$REMOVE"
也可以) - 最后分组并将 phone 推送给
_id
所有者
*为了加快速度,您需要 ContactLables.value
和 MongoDB 5 上的多键索引(此处查询是为了让 MongoDB 5 更快并使用 idenx)
Company.aggregate(
[{"$unwind":"$phones"},
{"$lookup":
{"from":"ContactLables",
"localField":"phones.label",
"foreignField":"values.code",
"pipeline":
[{"$unwind":"$values"},
{"$match":{"$expr":{"$eq":["$values.code", "$$label"]}}},
{"$project":{"_id":0, "value":"$values.value"}}],
"as":"results",
"let":{"label":"$phones.label"}}},
{"$set":{"phones.value":{"$first":"$results.value"}}},
{"$unset":["results"]},
{"$group":
{"_id":"$_id",
"company":{"$first":"$company"},
"phones":{"$push":"$phones"}}}])
查询2
- 同上,但管道内部使用reduce代替unwind和match
- reduce 以查找匹配的成员,并保留其值,例如“Home”
Company.aggregate(
[{"$unwind":"$phones"},
{"$lookup":
{"from":"ContactLables",
"localField":"phones.label",
"foreignField":"values.code",
"pipeline":
[{"$project":
{"_id":0,
"value":
{"$reduce":
{"input":"$values",
"initialValue":null,
"in":
{"$let":
{"vars":{"v":"$$value"},
"in":
{"$cond":
[{"$eq":["$$this.code", "$$label"]}, "$$this.value",
"$$v"]}}}}}}}],
"as":"results",
"let":{"label":"$phones.label"}}},
{"$set":{"phones.value":{"$first":"$results.value"}}},
{"$unset":["results"]},
{"$group":
{"_id":"$_id",
"company":{"$first":"$company"},
"phones":{"$push":"$phones"}}}])