Mongo:字段$的索引

时间:2014-06-11 11:42:00

标签: mongodb mongoose mongodb-query mongodb-indexes mongoose-plugins

我有以下mongoose架构:

var dataSchema = new Schema({  
    owner: { type: Schema.ObjectId, ref: 'User' },  
    time : { type: Date, default: Date.now },  
    eventCount:Number  
});

对于某些dataObjects,定义了eventCount并且为正数,对于其他dataObjects,eventCount是未定义的。我想设计一个索引,以便像这样的查询尽可能快:

db.datacollection.find({owner: <some ID>, eventCount: {$exists:true}, time: {<some time range>})

这样做的最佳方式是什么?

这是我能想到的最佳解决方案,但我有兴趣知道是否有人有更好的解决方案:

将isEventCount布尔变量添加到dataSchema。设置mongoose中间件,以便在使用以下逻辑将对象保存到db之前计算isEventCount。

if(eventCount > 0) {
    isEventCount = true;
} else {
    isEventCount = false;
}

然后构建像这样的索引

db.datacollection.ensureIndex({user:1, isEventCount: 1, time:1})

并像这样运行我的查询

db.datacollection.find({owner: <some ID>, isEventCount: true, time: {<some time range>})

这种方法有一些缺点。即:

  1. 我正在保存数据库中的冗余信息。
  2. 我必须编写额外的中间件代码才能实现这一目标。
  3. 我必须修改db中的现有条目。
  4. 是否有人知道更好的解决方案或可以帮助解决此问题的库?

1 个答案:

答案 0 :(得分:0)

你不需要通过所有这些来获得这个查询的不错表现。使用现有查询:

db.datacollection.find({owner: <some ID>, eventCount: {$exists:true}, time: {<some time range>}

这个指数:

db.datacollection.ensureIndex({user:1, eventCount: 1, time:1})
在大多数情况下,应该给你相当不错的表现。显然我不知道你现有数据集的大小或分布,但我认为你需要创建一个isEventCount标志,这需要一些相当不寻常的东西。

一般来说,在使用MongoDB中的模式设计采取任何异常措施之前,我会执行以下操作:

1)设置合理数量的测试数据 2)使用explain()

尝试查询

它可以让您很好地了解查询的执行情况以及使用索引的时间和时间。

http://docs.mongodb.org/manual/reference/method/cursor.explain/#cursor.explain