【问题标题】:MongoDB aggregation filtering of a nested object嵌套对象的MongoDB聚合过滤
【发布时间】:2021-02-13 10:14:41
【问题描述】:

我需要过滤一组嵌套对象,只返回那些将active.email 设置为 true 的对象。

到目前为止,我有一个聚合:

db.subscriptions.aggregate([
  {
    $match: { user: ObjectId('5f9a4f3070bd08b002498d43') },
  },
  {
    $project: {
      'subscriptions.user': 1,
      'subscriptions.active.email': 1,
    },
  })

返回单个用户的订阅文档:

{
    "_id" : ObjectId("5f9a4f3170bd08b002498d44"),
    "subscriptions" : [ 
        {
            "active" : {
                "email" : true
            },
            "user" : ObjectId("5f9a4e5071713dc6120df47f")
        }, 
        {
            "active" : {
                "email" : true
            },
            "user" : ObjectId("5f9b7f2dc16811a281113ba1")
        }, 
        {
            "active" : {
                "email" : false
            },
            "user" : ObjectId("5f9b7e8ac16811a281113b9f")
        }
    ]
}

如果我尝试对其使用过滤器:

db.subscriptions.aggregate([
  {
    $match: { user: ObjectId('5f9a4f3070bd08b002498d43') },
  },
  {
    $project: {
      'subscriptions.user': 1,
      'subscriptions.active.email': 1,
    },
  },
  {
    $filter: {
      input: '$subscriptions',
      as: 'subs',
      cond: { '$$subs.active.email': true },
    },
  },

它给了我这个错误:"Unrecognized pipeline stage name: '$filter'",

这是我想要的输出:


"subscriptions" : [ 
        {
            "active" : {
                "email" : true
            },
            "user" : ObjectId("5f9a4e5071713dc6120df47f")
        }, 
        {
            "active" : {
                "email" : true
            },
            "user" : ObjectId("5f9b7f2dc16811a281113ba1")
        }, 
    ]

在此使用过滤器的正确方法是什么?我最初尝试在查询中使用$elemMatch,但由于它是嵌套的,所以无法这样做。另外,如果有其他方法,我会全力以赴。

【问题讨论】:

    标签: javascript mongodb mongoose aggregation


    【解决方案1】:

    您需要在 $match'ed 主 _id 后展开“订阅”数组,然后您需要在活动邮件上再次 $match。使用 $project 创建更好的输出。确保您只查询一个主要的 _id,否则这会导致多个潜在不同用户的项目变得混乱。

    db.subscriptions.aggregate([
      {
        $match: { _id: ObjectId('5f9a4f3170bd08b002498d44') },
      },
      {
        $unwind: {
          path: '$subscriptions',
        },
      },
      {
        $match: {
          'subscriptions.active.email': true,
        },
      },
      {
        $project: {
          activeUserId: '$subscriptions.user',
          _id: 0,
        },
      },
    ])
    

    【讨论】:

    • 谢谢。我只是在你发送它时弄清楚这一点。我知道过滤器是错误的选择,但我仍然对使用$filter 的位置和时间感到困惑。似乎没有太多问题。
    猜你喜欢
    • 2020-08-19
    • 2015-03-10
    • 1970-01-01
    • 2022-01-22
    • 2018-01-30
    • 2014-12-31
    • 2020-01-24
    • 2020-04-23
    • 1970-01-01
    相关资源
    最近更新 更多