Question

I'm quite new to MongoDb and I'm trying to get my head around the grouping/counting functions. I want to retrieve a list of votes per track ID, ordered by their votes. Can you help me make sense of this?

List schema:

{
    "title" : "Bit of everything",
    "tracks" : [ 
        ObjectId("5310af6518668c271d52aa8d"), 
        ObjectId("53122ffdc974dd3c48c4b74e"), 
        ObjectId("53123045c974dd3c48c4b74f"), 
        ObjectId("5312309cc974dd3c48c4b750")
    ],
    "votes" : [ 
        {
            "track_id" : "5310af6518668c271d52aa8d",
            "user_id" : "5312551c92d49d6119481c88"
        }, 
        {
            "track_id" : "53122ffdc974dd3c48c4b74e",
            "user_id" : "5310f488000e4aa02abcec8e"
        }, 
        {
            "track_id" : "53123045c974dd3c48c4b74f",
            "user_id" : "5312551c92d49d6119481c88"
        }
    ]
}

I'm looking to generate the following result (ideally ordered by the number of votes, also ideally including those with no entries in the votes array, using tracks as a reference.):

[
 {
   track_id: 5310af6518668c271d52aa8d,
   track_votes: 1
 },
 {
   track_id: 5312309cc974dd3c48c4b750,
   track_votes: 0
 }
 ...
]

In MySQL, I would execute the following

SELECT COUNT(*) AS track_votes, track_id FROM list_votes GROUP BY track_id ORDER BY track_votes DESC

I've been looking into the documentation for the various aggregation/reduce functions, but I just can't seem to get anything working for my particular case.

Can anyone help me get started with this query? Once I know how these are structured I'll be able to apply that knowledge elsewhere!

I'm using mongodb version 2.0.4 on Ubuntu 12, so I don't think I have access to the aggregation functions provided in later releases. Would be willing to upgrade, if that's the general consensus.

Many thanks in advance!

Was it helpful?

Solution

I recommend you to upgrade your MongoDB version to 2.2 and use the Aggregation Framework as follows:

db.collection.aggregate(
   { $unwind:"$votes"},
   { $group : { _id : "$votes.track_id", number : { $sum : 1 } } }
)

MongoDB 2.2 introduced a new aggregation framework, modeled on the concept of data processing pipelines. Documents enter a multi-stage pipeline that transforms the documents into an aggregated result.

The output will look like this:

{
    "result":[
        {
            "_id" : "5310af6518668c271d52aa8d", <- ObjectId
            "number" : 2
        },
        ...

    ],
    "ok" : 1
}

If this is not possible to upgrade, I recommend doing it in a programmatically way.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top