MongoDB,通过索引字段上的正则表达式进行查询的性能

dam*_*hat 31 regex indexing mongodb mongodb-query

我希望按名称查找帐户(在50个帐户的MongoDB集合中)

通常的方式:我们用字符串找到

db.accounts.find({ name: 'Jon Skeet' })  // indexes help improve performance!
Run Code Online (Sandbox Code Playgroud)

正则表达怎么样?这是一项昂贵的操作吗?

db.accounts.find( { name: /Jon Skeet/ }) // worry! how indexes work with regex?
Run Code Online (Sandbox Code Playgroud)

编辑:

根据WiredPrairie:
MongoDB使用RegEx的前缀来查找索引(例如:)/^prefix.*/:

db.accounts.find( { name: /^Jon Skeet/ })  // indexes will help!'
Run Code Online (Sandbox Code Playgroud)

MongoDB $正则表达式

小智 31

实际上根据文档,

如果该字段存在索引,则MongoDB会将正则表达式与索引中的值进行匹配,这可能比收集扫描更快.如果正则表达式是"前缀表达式",则可以进一步优化,这意味着所有可能的匹配都以相同的字符串开头.这允许MongoDB从该前缀构造"范围",并且仅匹配来自该范围内的索引的那些值.

http://docs.mongodb.org/manual/reference/operator/query/regex/#index-use

换一种说法:

对于/ Jon Skeet/regex,mongo将完全扫描索引中的键,然后将获取匹配的文档,这可能比收集扫描更快.

对于/ ^ Jon Skeet/regex,mongo将仅扫描以索引中的正则表达式开头的范围,这将更快.


Seb*_*ian 13

如果有人仍然对搜索性能有问题,有一种方法可以优化正则表达式搜索,即使它搜索句子中的单词(不一定在字符串的开头^或结尾)。$

该字段应该有一个文本索引

db.someCollection.createIndex({ someField: "text" })
Run Code Online (Sandbox Code Playgroud)

并且仅在首先执行简单搜索后才应使用正则表达式进行查询

db.someCollection.find({ $and: 
  [
    { $text: { $search: "someWord" }}, 
    { someField: { $elemMatch: {$regex: /test/ig, $regex: /other/ig}}}
  ]
})
Run Code Online (Sandbox Code Playgroud)

这确保了正则表达式仅针对初始的普通搜索的结果运行,由于该字段上的索引,该搜索应该相当快。它可能会对搜索性能产生巨大影响,具体取决于集合有多大。