在MongoDB中返回数组项的子集

6

有人能提供如何返回数组子集的建议吗?例如,假设我有一个包含简单_id键和包含对象数组的键的文档集合(类似下面的示例),我想要找到所有符合简单条件的_id和匹配对象:

// campaigns
{
  "_id" : "Fred's C25K",
  "campaignData" : [
    {
      "date" : "2015-06-17",
      "source" : "nike"
    },
    {
      "date" : "2015-06-17",
      "source" : "reebok",
    },
    {
      "date" : "2015-06-12",
      "source" : "nike"
    },
    {
      "date" : "2015-06-14",
      "source" : "adidas"
    },
  ]
},
{
  "_id" : "Mike's Marathon",
  "campaignData" : [
    {
      "date" : "2015-06-17",
      "source" : "nike"
    }
  ]
},
{
  "_id" : "Jacob's Jamboree",
  "campaignData" : [
    {
      "date" : "2015-06-17",
      "source" : "keen"
    }
  ]
}

我希望我的结果包含 _id 和在“2015-06-17”这个日期值下匹配的所有对象。
// GOAL => To generate a result set that looks like:
{
  "_id" : "Fred's C25K",
  "campaignData" : [
    {
      "date" : "2015-06-17",
      "source" : "nike"
    },
    {
      "date" : "2015-06-17",
      "source" : "reebok",
    }
  ]
},
{
  "_id" : "Mike's Marathon",
  "campaignData" : [
    {
      "date" : "2015-06-17",
      "source" : "nike"
    }
  ]
},
{
  "_id" : "Jacob's Jamboree",
  "campaignData" : [
    {
      "date" : "2015-06-17",
      "source" : "keen"
    }
  ]
}
1个回答

3
使用聚合框架来实现所需结果。以下管道由$match运算符阶段组成,作为第一步来过滤应通过管道的文档。
下一阶段是$addFields运算符,它允许您输出包含输入文档中所有现有字段和新添加字段的文档。
在此步骤中,您可以使用$filter运算符根据指定的过滤器选择要返回的数组子集:
db.collection.aggregate([
    { "$match": {
        "campaignData.date" : "2015-06-17"
    } },
    { "$addFields": {
        "campaignData": {
            "$filter": {
                "input": "$campaignData",
                "cond": {
                    "$eq": ["$$this.date", "2015-06-17"]
                }
            }
        }
    } }
])

结果:

/* 0 */
{
    "result" : [ 
        {
            "_id" : "Mike's Marathon",
            "campaignData" : [ 
                {
                    "date" : "2015-06-17",
                    "source" : "nike"
                }
            ]
        }, 
        {
            "_id" : "Jacob's Jamboree",
            "campaignData" : [ 
                {
                    "date" : "2015-06-17",
                    "source" : "keen"
                }
            ]
        }, 
        {
            "_id" : "Fred's C25K",
            "campaignData" : [ 
                {
                    "date" : "2015-06-17",
                    "source" : "nike"
                }, 
                {
                    "date" : "2015-06-17",
                    "source" : "reebok"
                }
            ]
        }
    ],
    "ok" : 1
} 

1
非常感谢!!!我没想到需要两次匹配日期,但现在完全明白了。 - R Brennan
@RBrennan 没问题,很高兴能帮助到你。 - chridam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接