我正在使用MongoDB版本2.4.8。
[test] 2014-03-25 14:42:13.0 >>> db.users.getIndexes();
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"ns" : "test.users",
"name" : "_id_"
},
{
"v" : 1,
"key" : {
"username" : 1,
"age" : 1
},
"ns" : "test.users",
"name" : "username_1_age_1"
},
{
"v" : 1,
"key" : {
"age" : 1,
"username" : 1
},
"ns" : "test.users",
"name" : "age_1_username_1"
}
]
[test] 2014-03-25 14:44:36.550 >>>
[test] 2014-03-25 14:33:12.945 >>> db.users.find({"age" : 14, "username" : /.*/}).explain()
{
"cursor" : "BtreeCursor age_1_username_1 multi",
"isMultiKey" : false,
"n" : 16850,
"nscannedObjects" : 16850,
"nscanned" : 16850,
"nscannedObjectsAllPlans" : 16850,
"nscannedAllPlans" : 16850,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 86,
"indexBounds" : {
"age" : [
[
14,
14
]
],
"username" : [
[
"",
{
}
],
[
/.*/,
/.*/
]
]
},
"server" : "server01:27017"
}
解释输出在username
部分中意味着什么?
"username" : [
[
"",
{
}
],
[
/.*/,
/.*/
]
]
我很难理解这部分没有 如果我正式和非正式地看待它。
答案 0 :(得分:1)
那里的输出特别适用于未绑定到字符串起始位置的正则表达式。因此,对于要扫描索引而不是集合的正则表达式(即使在这种情况下它将扫描整个索引),需要有一组起始边界和结束边界:
考虑使用不同正则表达式的第一个查询:
db.collection.find({ "username": /bob/ }).explain()
"indexBounds" : {
"username" : [
[
"",
{
}
],
[
/bob/,
/bob/
]
]
},
因此,表示存在要搜索的整个字符串,然后匹配将以包含“bob”作为字符串一部分的内容结束。所以第一部分是“词汇”匹配边界,第二部分是要应用的实际正则表达式:
以下查询更清楚地显示了这一点:
db.collection.find({ username: /^bob/ }).explain()
"indexBounds" : {
"username" : [
[
"bob",
"boc"
],
[
/^bob/,
/^bob/
]
]
},
由于它锚定在字符串的开头,因此需要测试的索引的唯一条目与“bob”和“boc”之间的“词法”匹配。正则表达式再次作为边界的第二部分包含在内。
边界条目通常在内部被描述为“两部分”元素,正则表达式就是这种情况,在第一部分中有字符串边界,这对于匹配索引是有意义的,然后是正则表达式应用那些匹配的人。
作为最后一点,请参阅以下内容:
db.collection.find({ username: {$gt: ""} }).explain()
"indexBounds" : {
"username" : [
[
"",
{
}
]
]
},
这与您的初始查询本质上相同,即匹配任何字符串。