0

I'm attempting to use use the new MongoDB aggregation features to tally some statistics by date. Below is a sample of the documents that I am working with, my attempted code and desired result. The aggregation function retuns "UNDEFINED". Can someone tell me why that is? And secondly, I want my aggregation function to group results by date in mm-dd-yyyy format. However as it is currently written I think the code is going to execute the aggregation by the full ISO date. Can someone please tell me how to fix this?

DOCUMENT EXAMPLE

{
  user: "2A8761E4-C13A-470E-A759-91432D61B6AF-25982-0000352D853511AF",
  language: "English",
  imageFileName: "F7A5ED9-D43C-4671-A5C6-F06C7E41F902-7758-000008371FB5B834",
  audioFileName: "F6D5727D-9377-4092-A28A-AA900F02653D-7758-0000083749066CF2",
  date: ISODate("2012-10-22T02:43:52Z"),
  correct: "1",
  _id: ObjectId("5084b2e8179c41cc15000001")
}

AGGREGATION FUNCTION

    var getUserStats = function(user, language, callback) {
    var guessCollection = db.collection('Guesses');
    guessCollection.aggregate(
  { $match: {
    user: user,
    language: language,
  }},
  { $sort: {
    date: 1
  }},
  { $project : {
     user : 1,
            language : 1,
            date : 1,
            correct : 1,
            incorrect : 1,
  } },
  { $unwind : "$language" },
  { $group : {
     _id : "$date",
            correct : { $sum : "$correct" },
            incorrect : { $sum : "$incorrect" }
  } }
, function(err, result){
    console.log(result);
    callback(result);
});

DESIRED RESULT

  {
        "result" : [
    //...snip...
            {
                "_id" : "2A8761E4-C13A-470E-A759-91432D61B6AF-25982-0000352D853511AF",
                "correct" : 32,
                "incorrect" : 17,
                "date" : 2012-10-22
            },
{
                "_id" : "2A8761E4-C13A-470E-A759-91432D61B6AF-25982-0000352D853511AF",
                "correct" : 16,
                "incorrect" : 7,
                "date" : 2012-10-23
            }
        ],
        "Ok" : 1
    }

1 Answer 1

4

Regarding your first question about it returning undefined, there are two problems:

  1. You are using the $unwind operator on a field ($language) that isn't an array.
  2. You are using the $sum operator on a string field ($correct); that's only supported for number fields.

For your second question about grouping on just the date, you need to project the date components you want to group on and then use those components in your $group operator's _id value:

For example:

test.aggregate(
    { $match: {
        user: user,
        language: language
    }},
    { $sort: {
        date: 1
    }},
    { $project : {
        user : 1,
        language : 1,
        year : { $year: '$date' },
        month : { $month: '$date' },
        day : { $dayOfMonth: '$date'},
        correct : 1,
        incorrect : 1
    }},
    { $group : {
        _id : { year: "$year", month: "$month", day: "$day" },
        correct : { $sum : "$correct" },
        incorrect : { $sum : "$incorrect" }
    }},
    function(err, result){
        console.log(result);
    }
);

Produces output of:

[ { _id: { year: 2012, month: 10, day: 22 },
    correct: 0,
    incorrect: 0 } ]

You can assemble that into '2012-10-22' in code from there.

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

1 Comment

Correct on both. I just tried both parts of your answer and it works beautifully. Thanks very much! +1

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.