1

With this given data.

{ "_id" : 0, "a" : 0, "b" : 0, "c" : 21 }
{ "_id" : 1, "a" : 0, "b" : 0, "c" : 54 }
{ "_id" : 2, "a" : 0, "b" : 1, "c" : 52 }
{ "_id" : 3, "a" : 0, "b" : 1, "c" : 17 }
{ "_id" : 4, "a" : 1, "b" : 0, "c" : 22 }
{ "_id" : 5, "a" : 1, "b" : 0, "c" : 5 }
{ "_id" : 6, "a" : 1, "b" : 1, "c" : 87 }
{ "_id" : 7, "a" : 1, "b" : 1, "c" : 97 }

The query is this

db.fun.aggregate([{
    $group: {
        _id: { a: "$a", b: "$b" },
        c: { $max: "$c" }
    }
}, {
    $group: {
        _id: "$_id.a",
        c: { $min: "$c" }
    }
}])

The correct answer is

54 and 22

How come is it like that? I was expecting to be 97 and 21

Why have I thought of 97 as max and 21 as min? becaus all of the documents that has a similar values(namely a and b) c is the highest and the lowest is 21

can someone eloborate this to me? and how $group really work?

1
  • the correct answer is 52 and 22, not 54 and 22. Commented Sep 15, 2013 at 12:09

2 Answers 2

1

First $group gives you result of grouping by a and b and selecting max value of c. So, for example, it gets a=0 and b=0 combinations:

{ "_id" : 0, "a" : 0, "b" : 0, "c" : 21 }
{ "_id" : 1, "a" : 0, "b" : 0, "c" : 54 }

and for this it will group them and select max of 21 or 54, which is 54. So you get this result for all groups:

    {
        "_id" : {
            "a" : 1,
            "b" : 1
        },
        "c" : 97
    },
    {
        "_id" : {
            "a" : 1,
            "b" : 0
        },
        "c" : 22
    },
    {
        "_id" : {
            "a" : 0,
            "b" : 1
        },
        "c" : 52
    },
    {
        "_id" : {
            "a" : 0,
            "b" : 0
        },
        "c" : 54
    }

This is what your second $group will get to work with. And at this time it groups by a and selects min of c. So you can see that for a=1 min of c (from 22 and 97) will be 22 and for a=0 min c (from 52 and 54) will be 52.

So it is how you get 22 and 52.

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

Comments

0

This problem is really easy to look at from a relational (SQL) perspective, because $group in your scenario is very similar to SQL's GROUP BY.

So, assuming your data was in a table called MongoData with columns A, B and C, this is how the select equivalent to your aggregation would look like:

select A, min(C) MinC
from (
    select A, max(C)
    from MongoData
    group by A, B
  ) X (A, C)
group by A;

The results after running step 1 of the aggregation (or the inner Select) are:

A   B   MaxC
------------
0   0   54
1   0   22
0   1   52
1   1   97

Step2 reduces this data by grouping only by A to:

A   MinC
--------
0   52
1   22

Take a look at this SQLFiddle to see how the data looks after each of the two steps: http://sqlfiddle.com/#!3/7d4f5/10

Comments

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.