1

I am giving MongoDB a shot and building a simple journal with MongoDB and PYTHON. I have this simple structure :

db.posts.findOne()
{
"waketime": ISODate("2016-03-18T11:20:00Z"),
"bedtime": ISODate("2016-03-18T22:00:00Z"),
"day": "day entry",
"dream": "dream entry",
"workout" : [{"type":"cardio"},{"time":45}],
"meditation" : [{"time":10},{"time":10}],
"sex": "none"
}

I am trying to get the time I spent working out and the time I spent working out per type of workout. For the last I have gotten to this :

cursor = db.posts.aggregate([
    {"$group": {"_id" : "$workout.type", "count": {"$sum": "$workout.time"}}}
])

it returns this :

{u'count': 0, u'_id': [u'cardio']}
{u'count': 0, u'_id': [u'strength']}

it seems to have grouped correctly on workout.type but it doesn't $sum workout.time

anyone can help me?

thank you

1 Answer 1

1

Note that the field workout is a list of documents. Your error is that you're treating this field as a subdocument. You will be able to solve your problem changing the data model and keep your aggregation as it is. So, try the following model instead:

db.posts.findOne()
{
"waketime": ISODate("2016-03-18T11:20:00Z"),
"bedtime": ISODate("2016-03-18T22:00:00Z"),
"day": "day entry",
"dream": "dream entry",
"workout" : {
    "type":"cardio",
    "time":45
},
"meditation" : {
    "type":"dunno",
    "time":10
},
"sex": "none"
}

EDIT:

okay but what if i have multiple workouts a day ?

Good point. Let's say that my answer above solves the problem in a bad way because I'm adding the limitation of doing only one workout per day. Let's go back to your something like your model where this limitation doesn't exist. I've needed to amend it anyway in order to make all the items in the lists equivalent

db.posts.findOne()
{
"waketime": ISODate("2016-03-18T11:20:00Z"),
"bedtime": ISODate("2016-03-18T22:00:00Z"),
"day": "day entry",
"dream": "dream entry",
"workout" : [{"type":"cardio", "time":45},{"type": "strength", "time":45}],
"meditation" : [{"time":10},{"time":10}],
"sex": "none"
}

For this example you can use $unwind as one of the steps in your aggregation pipeline:

db.posts.aggregate([{$unwind:{"$workout"}},{$group:{_id:"$workout.type", count:{$sum:"$workout.time"}}}])

I haven't tested it, but I hope it works.

Regards

Sign up to request clarification or add additional context in comments.

1 Comment

okay I see now I had a little error in my datamodel. thanks for showing how to use the $unwind ist seems to be working now.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.