返回 MongoDB 中数组项的子集

R B*_*nan 6 arrays mongodb node.js

任何人都可以提供有关如何返回数组项子集的建议吗?例如,假设我有一个文档集合(类似于下面的示例),其中包含一个简单的 _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"
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

我希望我的结果包含 _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"
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

chr*_*dam 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"]
                }
            }
        }
    } }
])
Run Code Online (Sandbox Code Playgroud)

结果:

/* 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
} 
Run Code Online (Sandbox Code Playgroud)