0

My collection show like this:

{
    "_id" : ObjectId("59f86edc91bd5107ed577f82"),
    "name" : "Name1",
    "stats" : [ 
        {
            "value" : 1.85,
            "money" : 2.0,
            "date" : ISODate("2017-09-30T11:47:00.000Z"),
            "result" : false
        }, 
        {
            "value" : 2.0,
            "money" : 2.0,
            "date" : ISODate("2017-09-29T19:27:16.000Z"),
            "result" : false
        }, 
        {
            "value" : 1.9,
            "money" : 2.0,
            "date" : ISODate("2017-09-29T13:21:40.000Z"),
            "result" : true
        }
    ],
    "price" : {
        "201710" : 1.5
    }
}
{
    "_id" : ObjectId("59f86edc91bd5107ed577f83"),
    "name" : "Name2",
    "stats" : [ 
        {
            "value" : 1.82,
            "money" : 2.0,
            "date" : ISODate("2017-10-22T14:30:22.000Z"),
            "result" : false
        }, 
        {
            "value" : 2.98,
            "money" : 2.0,
            "date" : ISODate("2017-10-19T18:12:18.000Z"),
            "result" : true
        }, 
        {
            "value" : 2.43,
            "money" : 2.0,
            "date" : ISODate("2017-10-18T19:43:09.000Z"),
            "result" : true
        }
    ],
    "price" : {}
}

So, I want to get all the stats elements that are between two dates. My first approach with aggregate has been:

db.getCollection('People').aggregate(
        {"$match": {"stats.date": {
            "$gte": new ISODate("2017-09-01T00:00:00.000Z"),
            "$lte": new ISODate("2017-09-30T00:00:00.000Z")}}},
        {"$unwind": "$stats"},
        {"$project": {
                "date": "$stats.date",
                "value": "$stats.value",
                "money": "$stats.money",
                "result": "$stats.result"}
        },
        {"$sort": {"date": -1}})

But it returns all the stats of all the People that meet the condition of the dates.

How would I have to do to return all the stats that meet that condition?

  • Your initial `$match` should also be using [`$elemMatch`](https://docs.mongodb.com/manual/reference/operator/query/elemMatch/) i.e `{ "$match": { "stats": { "$elemMatch": { "date": { "$gte": new Date("2017-09-01"), "$lt": new Date("2017-10-01") } } } }}` otherwise you are actually selecting more data than you need and not "within" the range. See also [Specify Multiple Conditions for Array of Documents](https://docs.mongodb.com/manual/tutorial/query-array-of-documents/#specify-multiple-conditions-for-array-of-documents) in the core documentation. – Neil Lunn Nov 02 '17 at 12:58
  • Core point though is you use `$filter` to "filter" arrays. Just as is demonstrated on the existing answers. – Neil Lunn Nov 02 '17 at 12:58

0 Answers0