【问题标题】:Lookup pipeline: `$match` local field `$in` array when from value is the array and local value is to be found查找管道:`$match` 本地字段 `$in` 数组当 from value 是数组并且要找到本地值时
【发布时间】:2019-12-09 06:14:09
【问题描述】:

我有 2 个收藏。我想对与 ID 匹配的集合 A 进行聚合。从那里,我想从集合 B 中查找集合 A(本地字段)中匹配的 ID 在集合 B(外部字段)的数组中。

所以基本上:

集合 A:

{
    _id: ObjectId('<id>')
},
{
    _id: ObjectId('<id>')
},
{
    _id: ObjectId('<id>')
}

集合 B:

{
    _id: ObjectId('<id>'),
    related: ['<id>', '<id>', '<id>', '<id>']
},
{
    _id: ObjectId('<id>'),
    related: ['<id>', '<id>', '<id>', '<id>']
},
{
    _id: ObjectId('<id>'),
    related: ['<id>', '<id>', '<id>', '<id>']
}

查询:

db.collection_a.aggregate({
    [$match: {_id: ObjectId('<id>')}],
    // other $lookups...
    [
        $lookup: {
            as: 'collection_b',
            from: 'collection_b',
            let: {id: '$_id'},
            pipeline: [
                {
                    $match: {
                        $expr: {$in: ['$related', '$$id']}
                    }
                }
                // sorts, projections, etc...
            ]
        }
    ]
    // sorts, projections, etc...
});

期望的结果:

[
    {
        _id: ObjectId('<id>'),
        collection_b: [
            {
                _id: ObjectId('<id>'),
                related: ['<id>', '<id>', '<id>', '<id>']
            },
            {
                _id: ObjectId('<id>'),
                related: ['<id>', '<id>', '<id>', '<id>']
            }
        ]
    },
]

结果:

$in requires an array as a second argument, found: objectId

现在,我知道可以切换它并在 Collection B 上查找 Collection A,但是,在这种情况下,这不是一个选项(仍然应该查询 Collection A,即使它不存在于集合 B)。最好将其保留为一个查询。

非常感谢任何帮助。

【问题讨论】:

    标签: mongodb aggregation-framework


    【解决方案1】:

    你能试试这个吗:

    db.collection_a.aggregate(
    [{ $match: { _id: ObjectId(' ') } },
    // other $lookups...
    {
        $lookup: {
            as: 'collection_b',
            from: 'collection_b',
            let: { id: { $toString: '$_id' } },
            pipeline: [
                {
                    $addFields: {
                        "related": {
                            "$cond": {
                                "if": {
                                    "$ne": [{ "$type": "$related" }, "array"]
                                },
                                "then": [],
                                "else": "$related"
                            }
                        }
                    }
                },
                {
                    $match: {
                        $expr: { $in: ['$$id', '$related'] }
                    }
                }
                // sorts, projections, etc...
            ]
        }
    }
               // sorts, projections, etc...
    ]);
    

    正如$in 所说,将数组作为第二个参数,并将您要搜索的值作为第一个参数。

    【讨论】:

    • 当然:$in 需要一个数组作为第二个参数,发现:缺失
    • 是:$in 需要一个数组作为第二个参数,发现:缺失
    • @CharlerP :您的所有文档是否都有相关字段 & 作为数组?让我知道如果几个文档没有相关字段与相关字段作为不同类型,我们可以根据该查询进行此查询
    • 嗯。看起来不会。
    • 在你有 $addFields 的地方添加时,会抛出相同的“$in 需要一个数组作为第二个参数,发现:缺失”。这修复了在$match 阶段之前将$addFields 添加到$lookup 管道时的错误,但是返回所有结果,而不仅仅是匹配?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-23
    • 2020-11-22
    • 1970-01-01
    • 2018-01-22
    • 1970-01-01
    • 2015-11-05
    • 1970-01-01
    相关资源
    最近更新 更多