返回MongoDB中的数组项的子集

时间:2015-06-19 16:12:18

标签: arrays node.js mongodb

有人可以就如何返回数组项的子集提供建议吗?例如,假设我有一个文档集合(类似于下面的示例),它包含一个简单的_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 个答案:

答案 0 :(得分:1)

使用 aggregation framework 来获得所需的结果。以下管道包含 $match 运算符阶段,作为筛选应通过管道的文档的第一步。下一阶段是 $unwind 运算符,它从输入文档中解构campaignData数组字段,以输出每个元素的文档。每个输出文档都使用元素值替换数组。然后,您需要另一个 $match 步骤来获取与给定日期条件匹配的子文档。然后,匹配的文档将用于下一个 $group 管道步骤,以使用 $push {{3保留原始数组}}

db.collection.aggregate([
    {
        "$match": {
            "campaignData.date" : "2015-06-17"
        }
    },
    {
        "$unwind": "$campaignData"
    },
    {
        "$match": {
            "campaignData.date" : "2015-06-17"
        }
    },
    {
        "$group": {
            "_id": "$_id",
            "campaignData": {
                "$push": "$campaignData"
            }
        }
    }
])

<强>结果

/* 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
}