我有一个像这样的mongo系列:
{
"A2_AboutMe": "",
"A2_Attributes": "|av|nv|",
"A2_Birthday": "",
"A2_DateCreated": "2010-11-25 22: 59: 00",
"A2_DateLast": "2011-11-18 12: 09: 36",
"A2_FK_A1_IDPerson": "0",
"A2_Firstname": "José Luis",
"A2_FirstnameC": "Jose Luis",
"A2_Gender": "m",
"A2_IDProfile": "1",
"A2_Keywords": "...|..",
"A2_Lastname": "test - test",
"A2_LastnameC": "_test test",
"A2_Locale": "",
"A2_Middlename": "",
"A2_Name": "José Luis test",
"A2_NameC": "Jose Luis test",
...
}
在A2_LastnameC和A2_FirstnameC上有索引 此集合中的3.000.000个文档,8 GB数据存储
在3-4秒内完成查询(PHP)
$collection->find(array(«A2_FirstnameC» => new MongoRegex("/jose/i")))->sort(array(«A2_LastnameC» => -1))->limit(10)
但有时类似的查询在不到100毫秒内完成。
我每次都能做些什么才能获得这种表现?
测试计算机是i7,8GB Ram(7由mongo使用),Windows 7
答案 0 :(得分:0)
索引不能用于不区分大小写的正则表达式查询,也不能用于非root的正则表达式(不以“^
”开头的那些)。由于您已将A2_Firstname
字段非规范化为A2_FirstnameC
,因此您还可以存储该字段大小写(即全部较低或全部为大写),并避免需要使用不区分大小写的正则表达式;但即使在这种情况下,如果您没有使用带根的正则表达式,您仍将对集合进行完整扫描。在这种情况下,您是否能够负担得起取决于您的具体用例。
答案 1 :(得分:0)
首先,索引不会用于非类似前缀的,不区分大小写的正则表达式。但在上面的查询中,索引可用于按A2_LastnameC
字段进行排序,因此速度很快。现在有了排序数据MongoDB将需要获得A2_FirstnameC
值,并在准备好10个匹配时将其与正则表达式匹配(它也将相对较快,因为它将使用索引来检索数据而不是从中读取整个文档磁盘)。根据数据顺序,它可能恰好匹配前10个文档 - 这是最好的情况,而且速度非常快,最糟糕的情况是最后10个文档必须扫描所有以前的索引条目。 / p>
如何加快速度?使用可以使用索引的查询,例如:«A2_FirstnameC» => new MongoRegex("/^jose/")
。或者你必须使用某种全文搜索。一种简单的方法是将字段(在您的情况下为A2_Firstname
)拆分为单词,将它们标准化(转换为小写,替换重音)并存储为数组。现在,数组字段的索引将用于快速搜索。