Returning a subset of array elements in MongoDB

Can anyone offer advice on how I got back a subset of the elements of an array? For example, suppose I have a set of documents (similar to the example below) containing a simple key _id and a key containing an array of objects.

I would like to find all _id and matching objects that match simple criteria:

// campaigns
{
  "_id" : "Fred 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 Marathon",
  "campaignData" : [
    {
      "date" : "2015-06-17",
      "source" : "nike"
    }
  ]
},
{
  "_id" : "Jacob Jamboree",
  "campaignData" : [
    {
      "date" : "2015-06-17",
      "source" : "keen"
    }
  ]
}

      

I would like my result to contain _id and any suitable objects, for example for the date value "2015-06-17"

// GOAL => To generate a result set that looks like:
{
  "_id" : "Fred C25K",
  "campaignData" : [
    {
      "date" : "2015-06-17",
      "source" : "nike"
    },
    {
      "date" : "2015-06-17",
      "source" : "reebok",
    }
  ]
},
{
  "_id" : "Mike Marathon",
  "campaignData" : [
    {
      "date" : "2015-06-17",
      "source" : "nike"
    }
  ]
},
{
  "_id" : "Jacob Jamboree",
  "campaignData" : [
    {
      "date" : "2015-06-17",
      "source" : "keen"
    }
  ]
}

      

+3


source to share


1 answer


Use an aggregation structure to achieve your desired result. The next pipeline consists of an operator stage as the first step to filter documents that must pass through the pipeline. The next step is a statement that deconstructs an array field from the input documents to output the document for each element. Each output replaces the array with the element's value. You will need one more step to get the subdocuments that meet the specified date criteria. The relevant documents will then be used in the next step to preserve the original array using the accumulator group operator $match

$unwind

campaignData

$match

$group

$push

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

      



Result

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

      

+1


source







All Articles