MongoDB-理解索引-db.explain

MongoDB-理解索引-db.explain,mongodb,mongoengine,flask-mongoengine,Mongodb,Mongoengine,Flask Mongoengine,我正在python中使用mongoengine。对于声明我的模型,我有以下代码: class Subject(Document): uri = StringField(required=True,unique=True) resources = ListField(ReferenceField('Resource')) meta = { 'indexes': [ {'fields': ['uri'], 'unique': True}

我正在python中使用mongoengine。对于声明我的模型,我有以下代码:

class Subject(Document):
    uri = StringField(required=True,unique=True)
    resources = ListField(ReferenceField('Resource'))
    meta = {
        'indexes': [
            {'fields': ['uri'], 'unique': True},
        ],
    }
我想检查索引是否按预期创建/工作,因此我转到mongo并执行:

db.subject.find({uri:'}).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上

更新


不确定这是否相关,但我有另一个域类,它也使用与索引相同的URI。(
Resource

解释非常简单。这些是界限-下限和上限。如果它们相等,则您正在搜索精确的字符串

你也可以这样做

db.subject.find({uri: { $gte: 'http://dbpedia.org/resource/Napoleon', 
                        $lte: 'http://dbpedia.org/resource/Putin' 
                }).explain() 
(虽然它在您的情况下没有多大意义,但在其他地方可能有用),这将导致不同的界限,从而产生范围结果


我认为这背后的原因是简化。与使用不同的字段来描述精确搜索和范围搜索不同,您可以通过这种方式来表达两者

解释很简单。这些是界限-下限和上限。如果它们相等,则您正在搜索精确的字符串

你也可以这样做

db.subject.find({uri: { $gte: 'http://dbpedia.org/resource/Napoleon', 
                        $lte: 'http://dbpedia.org/resource/Putin' 
                }).explain() 
(虽然它在您的情况下没有多大意义,但在其他地方可能有用),这将导致不同的界限,从而产生范围结果


我认为这背后的原因是简化。与使用不同的字段来描述精确搜索和范围搜索不同,您可以通过这种方式来表达两者

解释很简单。这些是界限-下限和上限。如果它们相等,则您正在搜索精确的字符串

你也可以这样做

db.subject.find({uri: { $gte: 'http://dbpedia.org/resource/Napoleon', 
                        $lte: 'http://dbpedia.org/resource/Putin' 
                }).explain() 
(虽然它在您的情况下没有多大意义,但在其他地方可能有用),这将导致不同的界限,从而产生范围结果


我认为这背后的原因是简化。与使用不同的字段来描述精确搜索和范围搜索不同,您可以通过这种方式来表达两者

解释很简单。这些是界限-下限和上限。如果它们相等,则您正在搜索精确的字符串

你也可以这样做

db.subject.find({uri: { $gte: 'http://dbpedia.org/resource/Napoleon', 
                        $lte: 'http://dbpedia.org/resource/Putin' 
                }).explain() 
(虽然它在您的情况下没有多大意义,但在其他地方可能有用),这将导致不同的界限,从而产生范围结果


我认为这背后的原因是简化。与使用不同的字段来描述精确搜索和范围搜索不同,您可以通过这种方式来表达两者

这很正常,因为uri上有一个唯一的索引,您可以在该索引上查询单个文档。 explain上的indexBounds告诉您,为了检索该特定文档,它从该索引的[下限,上限]开始扫描索引,在本例中,由于您在查询中指定了单个文档,因此该索引恰好相同。nscanned=1也验证了这一点


如果要查看不同的边界,请尝试将正则表达式指定为:
{uri:{$regex:'^的查询http://dbpedia*“}}
那么它可能需要扫描更多的文档,您将在explain()中得到不同的[上限,下限]这很正常,因为uri上有一个唯一的索引,您可以在该索引上查询单个文档。 explain上的indexBounds告诉您,为了检索此特定文档,它从该索引的[lower,upper]边界开始扫描索引,在本例中,由于您在查询中指定了单个文档,因此该索引恰好相同。nsCaned=1也验证了这一点


如果要查看不同的边界,请尝试将正则表达式指定为:
{uri:{$regex:'^的查询http://dbpedia*“}}
那么它可能需要扫描更多的文档,您将在explain()中得到不同的[上限,下限]这很正常,因为uri上有一个唯一的索引,您可以在该索引上查询单个文档。 explain上的indexBounds告诉您,为了检索该特定文档,它从该索引的[下限,上限]开始扫描索引,在本例中,由于您在查询中指定了单个文档,因此该索引恰好相同。nscanned=1也验证了这一点


如果要查看不同的边界,请尝试将正则表达式指定为:
{uri:{$regex:'^的查询http://dbpedia*“}}
那么它可能需要扫描更多的文档,您将在explain()中得到不同的[上限,下限]这很正常,因为uri上有一个唯一的索引,您可以在该索引上查询单个文档。 explain上的indexBounds告诉您,为了检索此特定文档,它从该索引的[lower,upper]边界开始扫描索引,在本例中,由于您在查询中指定了单个文档,因此该索引恰好相同。nsCaned=1也验证了这一点


如果要查看不同的边界,请尝试将正则表达式指定为:
{uri:{$regex:'^的查询http://dbpedia*“}}
那么它可能需要扫描更多的文档,您将在explain()中获得不同的[上、下]边界。

索引下界是包含的,而上界是独占的。这基本上是这样写的:“在索引中准确地找到这个字符串,没有范围”。@MarkusWMahlberg我手头只有一个旧的2.4版本,所以这可能已经改变了,但在这种情况下它不是真的。无论比较器(
$gte
v.
$gt
$lte
v.
$lt
),它总是显示相同的
索引边界。因此,似乎ex/inclusivity(正确的词是什么?)无法从解释中确定。@Fox:定义就是这样。索引边界只告诉您使用了什么。它的工作原理和预期的一样:使用索引,记录