【问题标题】:MongoDB, performance of query by regular expression on indexed fieldsMongoDB,通过正则表达式对索引字段的查询性能
【发布时间】:2013-07-04 07:39:38
【问题描述】:

我想按名称查找帐户(在 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 来查找索引(例如:/^prefix.*/):

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

MongoDB $regex

【问题讨论】:

标签: regex mongodb indexing mongodb-query


【解决方案1】:

其实根据文档,

如果字段存在索引,则 MongoDB 匹配正则 针对索引中的值的表达式,这可能比 收藏扫描。如果常规的可以进一步优化 表达式是一个“前缀表达式”,这意味着所有潜在的 匹配以相同的字符串开头。这允许 MongoDB 构建一个 来自该前缀的“范围”,并且仅匹配来自该前缀的那些值 范围内的索引。

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

换句话说:

对于/Jon Skeet/ regex,mongo 会全盘扫描索引中的键,然后获取匹配的文档,这比集合扫描更快。

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

【讨论】:

  • 如果有直接匹配(即:匹配字母a),则正则表达式可以正常工作。但是如果我匹配一个完整的单词结果需要更长的时间(即:angular)。这是跨越 6M 文档,有没有办法加快这些查询?超过 8 个字符需要 19-30 秒,但会立即返回 1-2 个字符。
  • @chovy,我认为 MongoDB 不是搜索文本中间出现的字符串的最佳工具 - 我建议查看 ElasticSearch 或任何其他全文搜索引擎。
【解决方案2】:

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

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

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

只有在先执行普通搜索后,查询才应使用正则表达式

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

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

【讨论】:

  • 感谢您的意见。不过,我必须处理两个搜索条件。整个单词,然后是单词的一部分。
  • 如果您不搜索完整的单词,这实际上不起作用。如果您按文本索引搜索,“some”将不返回任何内容。
猜你喜欢
  • 2011-11-05
  • 1970-01-01
  • 1970-01-01
  • 2011-12-27
  • 2013-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多