使用嵌套组的MongoDB查询

时间:2013-09-15 08:23:47

标签: mongodb aggregation-framework

使用这些给定的数据。

{ "_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 }

查询是

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

正确的答案是

54 and 22

怎么样那样?我原以为97 and 21

为什么我认为97为最大值,21为最小值?因为所有具有相似值的文件(即a和b) c是最高的,最低的是21

有人可以向我说这个吗? $ group如何真正起作用?

2 个答案:

答案 0 :(得分:1)

首先$group为您提供按ab分组并选择c的最大值的结果。因此,例如,它会获得a=0b=0组合:

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

为此,它会对它们进行分组并选择2154的最大值,即54。所以你得到所有群体的结果:

    {
        "_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
    }

这是您的第二个$group可以使用的内容。此时它按a分组并选择c分钟。因此,您可以看到a=1分钟c分钟(来自229722a=0分钟{{1} (来自c52)将54

所以你得到的是5222

答案 1 :(得分:0)

从关系(SQL)的角度来看,这个问题很容易看,因为你的场景中的$group与SQL的GROUP BY非常相似。

因此,假设您的数据位于名为MongoData且名为ABC的表中,这就是您的聚合的等效选项看起来如何:

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

运行聚合(或内部选择)的步骤1后的结果是:

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

Step2通过仅将A分组为:

来减少此数据
A   MinC
--------
0   52
1   22

看看这个SQLFiddle,看看这两个步骤之后数据的外观:http://sqlfiddle.com/#!3/7d4f5/10