我使用的是MongoDB,我有一系列具有以下结构的文档:
{
fName:"Foo",
lName:"Barius",
email:"fbarius@example.com",
search:"foo barius"
}
我正在构建一个函数,它将在search
字段上执行正则表达式搜索。为了优化性能,我已在搜索字段中为此集合编制索引。然而,事情仍然有点慢。所以我在示例查询上运行explain()
:
db.Collection.find({search:/bar/}).explain();
根据获胜计划,我看到使用了以下索引边界:
"search": [
"[\"\", {})",
"[/.*bar.*/, /.*bar.*/]"
]
第二组是有道理的 - 它从包含条形的任何东西看到包含条形的任何东西。然而,第一集让我感到困惑。它似乎在""
包含{}
排除的范围内。我担心这个额外的界限会减慢我的查询速度。有必要保留吗?如果不是,我怎么能阻止它被包括在内?
答案 0 :(得分:5)
我认为这就是mongodb与正则表达式一起使用的方式(参见https://scalegrid.io/blog/mongodb-regular-expressions-indexes-performance/)。请注意nscanned / totalKeysExamined值,如果它太大,则索引对您的查询无用。
另见: MongoDB, performance of query by regular expression on indexed fields
答案 1 :(得分:0)
这是mongo使用这种类型的正则表达式和索引的方式。我的意思是你正在搜索/ bar /而不是/ ^ bar /。
在该字段上指定索引时,它将从第一个字符开始编制索引。因此,“Foo barius”以F开头编号。由于您在该字段中的任何位置搜索“bar”,您必须在该字段上搜索整个索引,查看* bar *。
解释中的第一行说明了索引中的每条记录。
第二行说,只给我(1)中那些 bar 的指数。
底线:设计您的记录,以便他们有效地使用索引。对于字符串,请确保您的搜索位于字符串的开头,例如/ ^ bar /。如果我要按姓氏搜索,则需要先在索引字段中进行搜索。
作为练习,请在/ ^ bar /上进行解释。你不会得到你的数据,但第一个索引边界将是/ ^ bar / to / ^ bas /.
我希望我的意识流回答是有帮助的。
UDude
答案 2 :(得分:-1)
以为我会加两分钱。
前两个答案是正确的。如果从头开始搜索,则正则表达式只能使用标准索引。实际上,使用索引并使用正则表达式进行搜索会对搜索产生不利影响,因为它会尝试使用索引但不会成功。
还有另一种类型的索引可能对您的情况有用。 Mongo的文本索引。它根据空格对每个单词编制索引,因此可以对单词“foo”和“barius”进行索引搜索,这可能更有用