使用$ project阶段中的$ in运算符过滤数组

Tom*_*omG 10 mongodb mongodb-query aggregation-framework

现在,在$ filter数组聚合运算符中不可能使用$ in运算符.

假设这是文档架构:

{
    _id: 1,
    users: [
        {
            _id: 'a',
            accounts: ['x', 'y', 'z']
        },
        {
            _id: 'b',
            accounts: ['j','k','l']
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

我希望,使用aggregate,users根据数组的内容获取带有过滤数组的文档accounts.

如果$in将与合作$filter运营商,我希望它看起来像这样:

db.test.aggregate([
    {
        $project: {
            'filtered_users': {
                $filter: {
                    input: '$users',
                    as: 'user',
                    cond: {
                        $in: ['$$user.accounts', ['x']]
                    }
                }
            }
        }
    }
])
Run Code Online (Sandbox Code Playgroud)

和返回的filtered_users只有第一个用户,因为X他的账户.

但是,正如我所说,这不起作用,我得到错误:

"无效的运营商'$ in'"

因为$filter运营商不支持它.

现在我知道我可以$unwind使用常规$match运算符来实现它,但是随后需要使用$group将结果设置为数组的更长时间(并且更加丑陋)聚合- 我不希望这样

我的问题是,如果有其他方法来操纵$filter运算符以获得我想要的结果.

Ana*_*Pai 15

由于$in数组的聚合操作不支持,因此可以使用替代方法$setIsSubset.有关这方面的更多信息,请参阅链接.聚合查询现在看起来像

db.test.aggregate([
{
    $project: {
        'filtered_users': {
            $filter: {
                input: '$users',
                as: 'user',
                cond: {
                   $setIsSubset: [['x'], '$$user.accounts']           
                }
            }
        }
    }
}])
Run Code Online (Sandbox Code Playgroud)

此查询将仅返回具有[x]作为数组子集的元素user.accounts.


sty*_*ane 10

从MongoDB 3.4开始,您可以$in$project阶段中使用聚合运算符

db.collection.aggregate([     
    {         
        "$project": {             
            "filtered_users": {                 
                "$filter": {                     
                    "input": "$users",                     
                    "as": "user",                     
                    "cond": { "$in": [ "x", "$$user.accounts" ] }                     
                }  
            }         
        }     
    } 
])
Run Code Online (Sandbox Code Playgroud)