具有动态匹配条件的查询的索引策略

时间:2014-11-25 07:31:24

标签: mongodb indexing aggregation-framework

我有一个集合,它将保存机器数据和移动数据,数据在通道上捕获并保持在单一级别没有嵌入对象,结构如下

{
    "Id": ObjectId("544e4b0ae4b039d388a2ae3a"),
    "DeviceTypeId":"DeviceType1",
    "DeviceTypeParentId":"Parent1",
    "DeviceId":"D1",
    "ChannelName": "Login",
    "Timestamp": ISODate("2013-07-23T19:44:09Z"),
    "Country": "India",
    "Region": "Maharashtra",
    "City": "Nasik",
    "Latitude": 13.22,
    "Longitude": 56.32,
    //and more 10 - 15 fields
}

大多数查询都是聚合查询,用于Google Analytics控制台和实时分析, $ match 管道如下

{$match:{"DeviceTypeId":{"$in":["DeviceType1"]},"Timestamp":{"$gte":ISODate("2013-07-23T00:00:00Z"),"$lt":ISODate("2013-08-23T00:00:00Z")}}}

{$match:{"DeviceTypeParentId":{"$in":["Parent1"]},"Timestamp":{"$gte":ISODate("2013-07-23T00:00:00Z"),"$lt":ISODate("2013-08-23T00:00:00Z")}}}

我的许多DAL层查找查询和 findOne 查询主要基于 DeviceType DeviceTypeParentId 条件。

这个集合很庞大且不断增长,我用复合索引来支持这个查询,索引如下

[
        {
                "v" : 1,
                "key" : {
                        "_id" : 1
                },
                "name" : "_id_",
                "ns" : "DB.channel_data"
        },
        {
                "v" : 1,
                "key" : {
                        "DeviceType" : 1,
                        "Timestamp" : 1
                },
                "name" : "DeviceType_1_Timestamp_1",
                "ns" : "DB.channel_data"
        },
        {
                "v" : 1,
                "key" : {
                        "DeviceTypeParentId" : 1,
                        "Timestamp" : 1
                },
                "name" : "DeviceTypeParentId_1_Timestamp_1",
                "ns" : "DB.channel_data"
        }
]

现在我们将在 DeviceId 上添加对匹配条件的支持,如果我遵循与 DeviceType DeviceTypeParentId 相同的策略,不好,因为我对目前的方法感到失望,我正在创建许多索引,而且所有索引都是相同且巨大的。 他们做索引的任何好方法也是如此。我已经阅读了一些关于 Index Intersection 的内容,但不确定它会有什么帮助。

如果我有任何错误的方法,请指出,因为这是我的第一个项目,也是我第一次使用MongoDB。

1 个答案:

答案 0 :(得分:0)

这些索引都适合您的查询,包括您提议的新查询。支持三种查询的三个独立索引是快速查询的总体最佳选择。您可以在每个字段上放置索引并让规划器使用索引交集,但它不会像复合索引那样好。索引不一样,因为它们支持不同的查询。

我认为真正的问题是,指数的(显然)大内存足迹实际上是一个问题吗?由于分页索引和数据不在磁盘中,您是否有很多页面错误?