2016-07-05 67 views
15

我使用MongoDB的,我有文件具有以下结构的集合:指数边界上蒙戈的正则表达式搜索

{ 
    fName:"Foo", 
    lName:"Barius", 
    email:"[email protected]", 
    search:"foo barius" 
} 

我建立将执行在search场正​​则表达式搜索功能。为了优化性能,我将这个集合编入了搜索字段。但是,事情还是有点慢。于是我就在样品上查询的explain():获胜的计划下

db.Collection.find({search:/bar/}).explain(); 

看,我看到以下指标范围:

"search": [ 
     "[\"\", {})", 
     "[/.*bar.*/, /.*bar.*/]" 
] 

第二组是有道理的 - 它看起来从任何含有酒吧任何包含酒吧。但是,第一套让我感到困惑。它看起来在""的范围内,包括{}排他性。我担心这个额外的边界会减慢我的查询速度。是否有必要保持?如果不是,我如何防止它被包含?

+0

有同样的问题,你有没有找到解释? – kirhgoff

+0

@kirhgoff您正在使用哪个版本的mongoDB? – barbakini

+0

@kirhgoff你在用什么'mongoDB native'或'mongoose'。检查一下 - http://voidcanvas.com/mongoose-vs-mongodb-native/ –

回答

5

我认为这只是mongodb使用正则表达式的方式(请参阅https://scalegrid.io/blog/mongodb-regular-expressions-indexes-performance/)。只要注意nscanned/totalKeysExamined值,如果它太大,那么索引对您的查询就没用了。

参见: MongoDB, performance of query by regular expression on indexed fields

+0

同意,如MongoDB文档和https://stackoverflow.com/a/33219393中所述/ 8291949如果您的正则表达式不是“前缀表达式”,mongo将全面扫描索引中的键,然后将获取匹配的文档(应该比完整的集合扫描更快)。 – wp78de

0

这是蒙戈可与这种类型的正则表达式和索引的方式。我的意思是你正在搜索/ bar /而不是/^bar /。

当您在该字段上指定索引时,它将从第一个字符开始编制索引。因此,“Foo barius”从F开始索引。由于您正在搜索字段中的任何位置的“bar”,因此您必须搜索该字段上的整个索引,查找* bar *。

您的解释中的第一行指出查看索引中的每条记录。

第二行说,给我只能从那些索引(1)在他们酒吧。底线:设计您的记录,以便他们有效地使用索引。对于字符串,请确保您的搜索位于字符串的开头,例如/^bar /。如果我要按姓氏搜索,则需要首先在索引字段中进行搜索。

作为练习,请在/^bar /上进行说明。你不会得到你的数据,但是第一个索引边界将会是/^bar/to/^ bas /。

我希望我的意识流有帮助。

UDude

-1

想到我会加我两分钱。

前面两个答案是正确的。如果从头开始搜索,则正则表达式只能使用标准索引。实际上,使用正则表达式搜索索引和搜索可能会对搜索产生不利影响,因为它尝试使用索引但不会成功。

还有一种类型的索引可能对您的情况有用。 Mongo的文本索引。它的索引基于空间的每一个字,所以这将是能够做到两个词“foo”和“barius”,这可能是一个索引更多使用

下面是该文档: https://docs.mongodb.com/manual/core/index-text/