johnstaveley
johnstaveley

Reputation: 1499

MongoDb aggregate Match date part

I'm trying to do this query, basically get all the timepoints which are 9am-9.59am:

db.DataPoints.find({$where: "new Date(this.Head.Timestamp).getHours() === 9"}, {_id: 0, 'Body.PAC.Values.1': 1}) 

but as an aggregate query. You can't do a where in match

db.DataPoints.aggregate([{ $match : { "Head.Timestamp": { $hour: 9 } } },...

Doesn't work. Searching so far has yielded nothing.

edit: A sample document is as follows:

{
"_id" : "d5c75619-fe17-4618-9333-004e3ee67cb3",
"Head" : {
    "Timestamp" : ISODate("2015-05-20T04:20:00.000Z"),
    "RequestArguments" : {
        "Query" : "Inverter",
        "Scope" : "System"
    },
    "Status" : {
        "Code" : 0,
        "Reason" : "",
        "UserMessage" : ""
    }
},
"Body" : {
    "PAC" : {
        "Unit" : "W",
        "Values" : {
            "1" : 55
        }
    },
    "DAY_ENERGY" : {
        "Unit" : "Wh",
        "Values" : {
            "1" : 24
        }
    },
    "YEAR_ENERGY" : {
        "Unit" : "Wh",
        "Values" : {
            "1" : 55017
        }
    },
    "TOTAL_ENERGY" : {
        "Unit" : "Wh",
        "Values" : {
            "1" : 119228
        }
    }
}
}

Upvotes: 2

Views: 1851

Answers (1)

chridam
chridam

Reputation: 103365

A much better approach would be to use the $redact pipeline which is bit nicer than using $project for a logical condition and then using $match to filter that logical match. It will return all documents match the condition using $$KEEP and discards those that don't match using the $$PRUNE variable:

db.DataPoints.aggregate([
    { 
        "$redact": {
            "$cond": {
                "if": { 
                    "$eq": [
                        { "$hour" : "$Head.Timestamp" },
                        9
                    ]
                },
                "then": "$$KEEP",
                "else": "$$PRUNE"
            }
        }   
    }
])

The longer approach would be to create a new field with the $project operator that stores the hour value which you can then use in the next $match pipeline:

db.DataPoints.aggregate([
    { 
        "$project" : { 
             "hour" : { "$hour" : "$Head.Timestamp" },
             "Head": 1,
             "Body": 1 
        } 
    },
    { "$match": { "hour": 9 } }
])

Upvotes: 3

Related Questions