我有一个集合,它将保存机器数据和移动数据,数据在 channel 上捕获并保持在单一级别,没有嵌入对象,结构如下
{
"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
}
大部分查询是聚合查询,用于Analytics dashboard和实时分析,$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 层 find 查询和 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。
最佳答案
这些索引看起来都适合您的查询,包括您提议的新索引。就快速查询而言,支持三种查询的三个独立索引是整体最佳选择。您可以在每个字段上放置索引并让计划器使用索引交集,但它不会像复合索引那样好。索引不相同,因为它们支持不同的查询。
我认为真正的问题是,索引的(表面上)大内存占用实际上是一个问题吗?由于分页索引和数据出磁盘,您是否有很多页面错误?
关于mongodb - 具有动态匹配条件的查询的索引策略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27120986/