MongoDB - 了解索引 - db.explain
MongoDB - Understanding Indexes - db.explain
我在 python 中使用 mongo 引擎。为了声明我的模型,我有以下代码:
class Subject(Document):
uri = StringField(required=True,unique=True)
resources = ListField(ReferenceField('Resource'))
meta = {
'indexes': [
{'fields': ['uri'], 'unique': True},
],
}
我想检查索引是否按预期创建/工作,所以我去了 mongo 并执行了:
db.subject.find({uri:'http://dbpedia.org/resource/Napoleon'}).explain()
该命令的输出如下:
{
"cursor" : "BtreeCursor uri_1",
"isMultiKey" : false,
"n" : 1,
"nscannedObjects" : 1,
"nscanned" : 1,
"nscannedObjectsAllPlans" : 1,
"nscannedAllPlans" : 1,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 0,
"indexBounds" : {
"uri" : [
[
"http://dbpedia.org/resource/Napoleon",
"http://dbpedia.org/resource/Napoleon"
]
]
},
"server" : "ioannis-linux:27017",
"filterSet" : false
}
我在查看 mongodb 文档时无法理解的是,为什么我们在 indexBounds
中得到两个具有相同 uri 索引的条目。这是什么意思?这发生在我查找的任何 URI 上。
更新
不确定这是否相关,但我有另一个域 class 也使用与索引相同的 URI..(Resource
)
解释很简单。这些是边界——下限和上限。如果它们相等,那么您正在搜索一个精确的字符串。
你也可以这样做
db.subject.find({uri: { $gte: 'http://dbpedia.org/resource/Napoleon',
$lte: 'http://dbpedia.org/resource/Putin'
}).explain()
(尽管它在您的情况下没有多大意义,但在其他地方可能会有用),这将导致不同的界限,从而产生范围结果。
我想说这背后的原因是简化。您无需使用不同的字段来描述精确搜索和范围搜索,而是可以同时表达两者。
这很正常,因为您在 uri 上有一个唯一索引,并且您在该索引上查询单个文档。
explain 上的 indexBounds 告诉您的是,为了检索此特定文档,它扫描了从该索引的 [lower, upper] 边界开始的索引,在这种情况下恰好相同,因为您在查询中指定了单个文档。 nscanned = 1 也验证了这一点。
如果您想查看不同的边界,请尝试将正则表达式指定为以下查询:{uri: {$regex:'^"http://dbpedia*'}}
那么它可能必须扫描更多文档,您将在 explain() 中获得不同的 [upper, lower] 边界
我在 python 中使用 mongo 引擎。为了声明我的模型,我有以下代码:
class Subject(Document):
uri = StringField(required=True,unique=True)
resources = ListField(ReferenceField('Resource'))
meta = {
'indexes': [
{'fields': ['uri'], 'unique': True},
],
}
我想检查索引是否按预期创建/工作,所以我去了 mongo 并执行了:
db.subject.find({uri:'http://dbpedia.org/resource/Napoleon'}).explain()
该命令的输出如下:
{
"cursor" : "BtreeCursor uri_1",
"isMultiKey" : false,
"n" : 1,
"nscannedObjects" : 1,
"nscanned" : 1,
"nscannedObjectsAllPlans" : 1,
"nscannedAllPlans" : 1,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 0,
"indexBounds" : {
"uri" : [
[
"http://dbpedia.org/resource/Napoleon",
"http://dbpedia.org/resource/Napoleon"
]
]
},
"server" : "ioannis-linux:27017",
"filterSet" : false
}
我在查看 mongodb 文档时无法理解的是,为什么我们在 indexBounds
中得到两个具有相同 uri 索引的条目。这是什么意思?这发生在我查找的任何 URI 上。
更新
不确定这是否相关,但我有另一个域 class 也使用与索引相同的 URI..(Resource
)
解释很简单。这些是边界——下限和上限。如果它们相等,那么您正在搜索一个精确的字符串。
你也可以这样做
db.subject.find({uri: { $gte: 'http://dbpedia.org/resource/Napoleon',
$lte: 'http://dbpedia.org/resource/Putin'
}).explain()
(尽管它在您的情况下没有多大意义,但在其他地方可能会有用),这将导致不同的界限,从而产生范围结果。
我想说这背后的原因是简化。您无需使用不同的字段来描述精确搜索和范围搜索,而是可以同时表达两者。
这很正常,因为您在 uri 上有一个唯一索引,并且您在该索引上查询单个文档。 explain 上的 indexBounds 告诉您的是,为了检索此特定文档,它扫描了从该索引的 [lower, upper] 边界开始的索引,在这种情况下恰好相同,因为您在查询中指定了单个文档。 nscanned = 1 也验证了这一点。
如果您想查看不同的边界,请尝试将正则表达式指定为以下查询:{uri: {$regex:'^"http://dbpedia*'}}
那么它可能必须扫描更多文档,您将在 explain() 中获得不同的 [upper, lower] 边界