9

我有一个查询:

db.test.aggregate( {$group : { _id : '$key', frequency: { $sum : 1 } } } )

这将获得测试集中每个键的枚举频率。基本上,我已经得到了密钥的分配。

现在想象一下,我想获得 key1、key2 和 key3 的分布(所以三个不同的分布)。

显然,我可以使用每个单独的键运行此查询 3 次,但似乎我们可以通过允许它同时计算所有 3 个键来优化查询。我一直在玩它并搜索整个互联网,但到目前为止,我被委托运行三个单独的聚合查询或使用 map/reduce 函数。

有没有人有任何其他想法?

4

1 回答 1

6

您可以在这里使用几种不同的方法:

  1. 使用 map/reduce:不要这样做。现在运行聚合框架 3 次比在这个用例中使用 map reduce 函数要快得多。

  2. 运行聚合 3 次。这不是最佳选择,但如果您没有时间限制,那么这是最简单的选择。如果您的聚合花费了 < 几秒钟,那么在它们成为问题之前我不会担心优化。

  3. 这是我能想到的最好的解决方法。该运算符允许您在多个字段上$group构建一个。_id例如{"_id":{"a":"$key1", "b":"$key2", "c":"$key3"}}。这样做会为您的不同键的所有现有组合创建一个分组。您可以通过这种方式对密钥进行分组,然后手动汇总客户端中的结果。

让我详细说明。假设我们有一组形状。这些形状可以有颜色、大小和种类(正方形、圆形等)。多键 ID 上的聚合可能如下所示:

db.shapes.aggregate({$group:{_id:{"f1":"$f1", "f2":"$f2", "f3":"$f3"}, count:{"$sum":1}}})

并返回:

"result" : [
        {
            "_id" : {
                "f1" : "yellow",
                "f2" : "medium",
                "f3" : "triangle"
            },
            "count" : 4086
        },
        {
            "_id" : {
                "f1" : "red",
                "f2" : "small",
                "f3" : "triangle"
            },
            "count" : 4138
        },
        {
            "_id" : {
                "f1" : "red",
                "f2" : "big",
                "f3" : "square"
            },
            "count" : 4113
        },
        {
            "_id" : {
                "f1" : "yellow",
                "f2" : "small",
                "f3" : "triangle"
            },
            "count" : 4145
        },
        {
            "_id" : {
                "f1" : "red",
                "f2" : "small",
                "f3" : "square"
            },
            "count" : 4062
        }

... 等等

然后,您将在大大减少条目数量的情况下总结客户端的结果。假设每个键的唯一值数量与文档总数相比足够小,您可以在可以忽略不计的时间内完成此最后一步。

于 2013-09-18T18:36:04.583 回答