46

我想按名称查找帐户(在 50K 帐户的 MongoDB 集合中)

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

db.accounts.find({ name: 'Jon Skeet' })  // indexes help improve performance!

用正则表达式怎么样?这是一项昂贵的手术吗?

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

编辑:

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

db.accounts.find( { name: /^Jon Skeet/ })  // indexes will help!'

MongoDB $正则表达式

4

2 回答 2

45

实际上根据文档,

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

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

换句话说:

对于/Jon Skeet/正则表达式,mongo 将完整扫描索引中的键,然后获取匹配的文档,这可能比集合扫描更快。

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

于 2015-10-19T16:26:06.953 回答
7

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

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

db.someCollection.createIndex({ someField: "text" })

并且仅在先执行普通搜索后才应使用正则表达式的查询

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

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

于 2021-09-01T14:15:31.300 回答