MongoDB "JOIN" 聚合:如何在 $lookup 之后进行 $match?
MongoDB "JOIN" aggregation: How to $match after a $lookup?
我有两个集合:collA
和 collB
,我正在进行以下查找:
db.collA.aggregate([
{
$lookup: {from: 'collB', localField: '_id', foreignField: 'key', as: 'bs'}
}])
如果我们到此为止,那么 bs
是一个对象数组
每个“b”对象都有一个字段name
。
我只想过滤 bs
之一满足条件的记录:b.name == query_name
.
- 我认为
$elemMatch
不可能
- 我也认为我可以
$unwind
和 $group
但感觉像是开销。
有没有一种简单的方法可以按此条件进行筛选?
示例数据:
collA:
[
{"_id": "1", "a": 1, "b": 1},
{"_id": "2", "a": 2, "b": 2}
]
collB:
[
{"key": "1", "name": "Ron"},
{"key": "1", "name": "Bob"},
{"key": "1", "name": "Dana"},
{"key": "2", "name": "John"},
{"key": "2", "name": "Ron"}
]
因此,如果查询是 Ron
,我希望从 collA 获得这两个文档。如果查询是 Bob
我希望只得到带有 _id == 1
的文档
解决方案 1
在 $project
阶段使用 $filter
从数组 (bs
) 中过滤文档。
db.collA.aggregate([
{
$lookup: {
from: "collB",
localField: "_id",
foreignField: "refId",
as: "bs"
}
},
{
$project: {
_id: 1,
bs: {
"$filter": {
"input": "$bs",
"cond": {
$eq: [
"$$this.name",
/* Filter value */
]
}
}
}
}
}
])
Sample Solution 1 on Mongo Playground
解决方案 2
db.collA.aggregate([
{
$lookup: {
from: "collB",
let: {
id: "$_id"
},
pipeline: [
{
$match: {
$expr: {
$and: [
{
$eq: [
"$$id",
"$refId"
]
},
{
$eq: [
"$name",
/* Filter value */
]
}
]
}
}
}
],
as: "bs"
}
}
])
我有两个集合:collA
和 collB
,我正在进行以下查找:
db.collA.aggregate([
{
$lookup: {from: 'collB', localField: '_id', foreignField: 'key', as: 'bs'}
}])
如果我们到此为止,那么 bs
是一个对象数组
每个“b”对象都有一个字段name
。
我只想过滤 bs
之一满足条件的记录:b.name == query_name
.
- 我认为
$elemMatch
不可能 - 我也认为我可以
$unwind
和$group
但感觉像是开销。
有没有一种简单的方法可以按此条件进行筛选?
示例数据:
collA:
[
{"_id": "1", "a": 1, "b": 1},
{"_id": "2", "a": 2, "b": 2}
]
collB:
[
{"key": "1", "name": "Ron"},
{"key": "1", "name": "Bob"},
{"key": "1", "name": "Dana"},
{"key": "2", "name": "John"},
{"key": "2", "name": "Ron"}
]
因此,如果查询是 Ron
,我希望从 collA 获得这两个文档。如果查询是 Bob
我希望只得到带有 _id == 1
解决方案 1
在 $project
阶段使用 $filter
从数组 (bs
) 中过滤文档。
db.collA.aggregate([
{
$lookup: {
from: "collB",
localField: "_id",
foreignField: "refId",
as: "bs"
}
},
{
$project: {
_id: 1,
bs: {
"$filter": {
"input": "$bs",
"cond": {
$eq: [
"$$this.name",
/* Filter value */
]
}
}
}
}
}
])
Sample Solution 1 on Mongo Playground
解决方案 2
db.collA.aggregate([
{
$lookup: {
from: "collB",
let: {
id: "$_id"
},
pipeline: [
{
$match: {
$expr: {
$and: [
{
$eq: [
"$$id",
"$refId"
]
},
{
$eq: [
"$name",
/* Filter value */
]
}
]
}
}
}
],
as: "bs"
}
}
])