存储许多没有冗余字段的小文档

时间:2015-02-02 16:53:33

标签: mongodb aggregation-framework

这是mongoDB中经典的许多小文档与少数大文档问题的子集。现在我有一个大型的mongodb文档,如下所示:

//Collection: Everything
{
    _id: "1",
    date: Date(...),
    target: "192.168.0.7"
    tests: [
        {
            name: "Speed Test",
            components: [
                {
                    name: "Upload Test"
                    results: [ { "upload_speed_Mbps" : 5 }, ... ]
                },
                {
                    name: "Download Test"
                    results: [ ... ]
                },
                ...
            ]
        },
        ...
    ]
}

问题是很难利用mongoDB的聚合功能和这样的文档结构,因为如果我想要在两个日期之间记录在给定目标上的所有上传速度的数组,则上传速度统计是嵌套3个数组深,mongo不知道如何找到它,除非我做三重展开(我相信这是一个代价高昂的操作)。

因此,mongoDB似乎更好/更快地拥有像这样的较小文档的集合:

//Collection: Suites
{
    _id: "1",
    date: Date(...),
    target_ip: "192.168.0.7"
    tests: [
        "1a",
        "2a",
        "3a",
        ...
    ]
}

//Collection: Tests
{
    _id: "1a",
    name: "Speed Test",
    components: [
        "1b",
        "2b",
        "3b",
        ...
    ]
}

//Collection: Components
{
    _id: "1b",
    name: "Upload Test",
    results: [
        "1c",
        "2c",
        "3c",
        ...
    ]
}

//Collection: Results
{
    _id: "1c",
    name: "upload_speed_Mbps",
    value: 5
}

这样我可以直接在Results文档中聚合。现在我的问题是,如果我想快速汇总在两个日期之间在给定目标上发生的上传速度的集合,我唯一的选择是在每个文档中包含datetarget字段Results收藏?当信息已在顶级文档中访问时,这似乎是多余的。

我认为我可以:

  1. 在我的子文档中有冗余信息以获得快速聚合
    1. 我的子文档中没有冗余信息,但由于昂贵的展开操作而导致快速聚合?

1 个答案:

答案 0 :(得分:1)

当您对大型文档集合执行操作时,

$unwind操作通常很昂贵。这些文档本身具有大型数组或大型嵌套数组。

对于此查询,您可以在开头使用原始文档结构,只需targetdate范围$match。这限制了使用$unwind处理的数据的大小。您还可以$project进一步限制聚合将处理的数据量。这应该会大大降低查询的成本。

如果您仍然希望将所有组件分开,那么您需要在要查询的文档中包含您要查询的信息。