MongoDB索引数组问题

时间:2018-01-03 14:05:53

标签: mongodb

我对mongoDB(版本:" 3.4.10")索引数组有疑问,因为我发现它们无法正常工作。也许我做错了什么。

我的日程安排文件中有一些对这个问题不重要的道具。但是每个时间表都有它的计划(发生)时期。

  

{...."计划":[{" startDateTime":" 2018-01-04T00:00:00Z",   " endDateTime":" 2018-01-04T23:59:59Z" },{" startDateTime":   " 2018-01-11T00:00:00Z"," endDateTime":" 2018-01-11T23:59:59Z" } ...]   },

现在,我需要按该数组项搜索计划文档,并查找适合该期间的所有计划。 我创建了index plans.startDateTime和plans.endDateTime。

当我使用compas选项解释计划执行以下查询时,我的结果很糟糕。

  

{" Plans.StartDateTime":{$ lt:new Date(' 2018-01-10')}," Plans.EndDateTime":{$ gte:新日期(' 2018-01-15')}}

结果是(这是在测试环境中,文档数量非常少,生产比率会更高)

  • 文件退回:2823
  • 已检查的索引键:65708
  • 检查的文件:11554

当我进一步深入分析时,我得到了跟随(意味着mongo忽略了索引搜索中的计划结束日期):

  

" indexBounds":{" Plans.StartDateTime":["(true,new   日期(1515542400000))" ]," Plans.EndDateTime":[" [MinKey,   MaxKey]" ]},

有人可以告诉我如何为追踪搜索创建更好的索引,因为这个没有用吗?

1 个答案:

答案 0 :(得分:1)

为了找到至少有一个计划与给定时间间隔重叠的所有scheduleDocuments(例如2018-01-10和2018-01-14),您必须使用$elemMatch MongoDB运算符。

db.scheduleDocuments.find({
    plans: {
        $elemMatch: {
            startDateTime: { $lte: ISODate("2018-01-14Z") },
            endDateTime: { $gt: ISODate("2018-01-10Z") }
        }
    }
});

可以找到用于测试重叠间隔的规则here

此搜索执行集合扫描,除非您在阵列上创建索引。

db.scheduleDocuments.createIndex({
    "plans.startDateTime": 1,
    "plans.endDateTime": 1
});

由于索引,系统根本不扫描不匹配的文档。执行IXSCAN并且仅访问匹配文档以获取和返回。