【问题标题】:Filter array using the $in operator in the $project stage在 $project 阶段使用 $in 运算符过滤数组
【发布时间】:2016-09-12 07:00:26
【问题描述】:

目前,无法在 $filter 数组聚合运算符中使用 $in 运算符。

假设这是文档架构:

{
    _id: 1,
    users: [
        {
            _id: 'a',
            accounts: ['x', 'y', 'z']
        },
        {
            _id: 'b',
            accounts: ['j','k','l']
        }
    ]
}

我想使用aggregate,根据accounts 数组的内容获取过滤数组users 的文档。

IF $in 可以与 $filter 运算符一起使用,我希望它看起来像这样:

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

并返回filtered_users,只有自x以来的第一个用户他的帐户。

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

“无效的运算符'$in'”

因为 $filter 运算符不支持它。

现在我知道我可以使用 $unwind 并使用常规的 $match 运算符来做到这一点,但之后聚合时间会更长(而且更丑陋),因为需要使用 $group 将结果设置为数组- 我不想要这个

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

【问题讨论】:

    标签: mongodb mongodb-query aggregation-framework


    【解决方案1】:

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

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

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

      • 正确的格式应该是这样的: "cond": { "$in": [ "$$user.accounts", ["x"] ] }
      • @Eric 我不这么认为。 OP的查询是错误的。 OPs 想要的是在filtered_users 中只返回第一个用户,因为x 在他的帐户中。你错过了问题中的那部分。
      猜你喜欢
      • 2022-11-22
      • 2021-06-28
      • 2018-10-12
      • 2018-06-16
      • 1970-01-01
      • 2015-06-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多