【问题标题】:More granular limits in Mongo aggregate calls?Mongo 聚合调用中更精细的限制?
【发布时间】:2017-03-24 19:32:17
【问题描述】:

我有一个想在 Mongo 上运行的查询。基本上它看起来像这样:

db.getCollection('termStatistics').aggregate(
    { $filter: { "kind": 0 } },
    {
        $group:
        {
            "_id": "$termId",
            "count": {$sum: NumberLong(1)}
        }
    },
    { $sort: {"count": -1} },
    { $limit: 100 }
)

这将获取每个 termId 的计数,并为我提供前 100 个。但是,我必须对kind 的每个值运行相同的查询,其中有几个,因为用户想要每个类别的前 100 个。我想避免为单个查询多次返回 mongo(实际的过滤器也会执行一些特定于用户的过滤,因此缓存结果是不合理的)。

是否可以将所有这些组合成一个聚合调用?某种“每一种价值的限制”之类的?

编辑:这里有一些示例文档。这些有点愚蠢,但很难发布数千个对他们感兴趣的文档......假设我有这些 n 的副本(_ids),每个 n 在 1 到1000:

{ kind: 0, termId: n }

另外,我有n,每个n 介于 1 到 100 之间:

{ kind: 1, termId: n }

我想要的是每种类型的前 100 个termId。对于kind: 0,这将是[{ _id: 1000, count: 1000 }, ...{ _id: 901, count: 901 }],对于kind: 1,这将是[{ _id: 200, count: 200 }, ..., { _id: 101, count: 101 }]

这很容易做到,但需要两次聚合调用(见上文)。最好进行一次聚合调用并获得类似以下内容:

[
    { kind: 0, data: [{ _id: 1000, count: 1000 }, ...{ _id: 901, count: 901 }]},
    { kind: 1, data: [{ _id: 200, count: 200 }, ...{ _id: 101, count: 101 }]},
]

如果我们只是将限制提高到 200,我们将无法从 kind: 1 得到任何东西,因为从 kind: 0 有足够的常见 termIds,所以我需要一些其他类型的限制,或者一些真的巧妙地使用它。

希望这更清楚!

【问题讨论】:

    标签: mongodb database-performance


    【解决方案1】:

    不是 100% 确定您要做什么,但您可以尝试对“种类”字段和术语进行分组,而不是先对其使用 $match 或 $filter。

    类似:

    db.getCollection('termStatistics').aggregate(
        {
            $group: {
                "_id": {
                    "kind": "$kind",
                    "term": "$termId"
                },
                "count": {
                    $sum: NumberLong(1)
                }
            }
        },
        { $sort: {"count": -1} },
        { $limit: 100 }
    )
    

    【讨论】:

    • 这仍然只会返回 100 个文档。我基本上需要 600 个文档——每种类型的值 100 个。但是如果我将限制设置为 600,我可能会(例如)从最流行的那种中获得 500,因此从其余的那里就不够了。
    • 您能否发布一些示例文档以及您希望输出的内容?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-22
    • 1970-01-01
    • 1970-01-01
    • 2014-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多