【发布时间】:2011-12-27 18:30:28
【问题描述】:
我正在使用 MongoDB 创建我的第一个应用程序。 为字段创建索引,并尝试使用 $regex 参数进行查找查询,在 shell 中启动
> db.foo.find({A:{$regex:'BLABLA!25500[0-9]'}}).explain()
{
"cursor" : "BtreeCursor A_1 multi",
"nscanned" : 500001,
"nscannedObjects" : 10,
"n" : 10,
"millis" : 956,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {
"A" : [
[
"",
{
}
],
[
/BLABLA!25500[0-9]/,
/BLABLA!25500[0-9]/
]
]
}
}
这很奇怪,因为当我启动相同的查询,但集合中没有索引时,性能要好得多。
> db.foo.find({A:{$regex:'BLABLA!25500[0-9]'}}).explain()
{
"cursor" : "BasicCursor",
"nscanned" : 500002,
"nscannedObjects" : 500002,
"n" : 10,
"millis" : 531,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {
}
}
显然,在没有正则表达式的情况下搜索具有索引的字段工作得更快(即搜索具有常量字段的文档),但我真的对这种行为的原因很感兴趣。
【问题讨论】:
-
不知道是什么导致索引变慢,但是如果您希望正则表达式利用索引,您可以尝试
^BLABLA!25500[0-9]让 mongodb 知道第一个字符是什么(如果它适合您的用例)。 -
有效!我怎么会忘记...现在只需要 49 毫秒。谢谢!但是我仍然不知道为什么索引会变慢,如果 mongo 知道它不能使用索引并在集合中处理完整搜索......它如何关心索引? ...
-
@Lycha:这只是您做出的假设,并且是错误的:对索引字段执行正则表达式将使用该索引(不会扫描集合中的每个文档),即使正则表达式表达式没有说明前缀(即使正则表达式类似于 /.*whatever.*/)
-
@AndreiBodnarescu 你在哪里读到的?根据表现,我的建议似乎是正确的。这是来自 mongodb 网站的引述“对于像 /^prefix/ 这样的简单前缀查询(也称为根正则表达式),数据库将在可用且适当时使用索引”。基于此,它只会将索引用于前缀正则表达式。
-
我一定在他们的文档中错过了这一点,但是进行一些基本测试表明,对于基本(如文本)索引字段,进行正则表达式搜索将始终使用索引,即使您指定前缀与否。只要您使用点表示法(不是 $elemMatch),嵌入式数组字段也是如此。所以基本上,就搜索中的索引使用而言,如果您指定一个带有前缀或不带前缀的正则表达式,那么它是没有意义的
标签: regex mongodb indexing mongodb-indexes