1

我有以下猫鼬模式:

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. 我必须修改数据库中的现有条目。

有人知道更好的解决方案或可以帮助解决此问题的库吗?

4

1 回答 1

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

于 2014-06-11T14:20:30.567 回答