MongoDB - 了解索引 - db.explain

时间:2015-04-10 10:17:36

标签: 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},
        ],
    }

我想检查索引是否按预期创建/工作,所以我去了mongo并执行:

  

db.subject.find({URI:' http://dbpedia.org/resource/Napoleon'})。解释()

该命令的输出如下:

{
    "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

2 个答案:

答案 0 :(得分:2)

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

你也可以这样做

db.subject.find({uri: { $gte: 'http://dbpedia.org/resource/Napoleon', 
                        $lte: 'http://dbpedia.org/resource/Putin' 
                }).explain() 

(虽然它在你的情况下没有多大意义,但在其他地方可能会有用),这会导致不同的界限,从而导致范围结果。

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

答案 1 :(得分:1)

这很正常,因为您在uri上有一个唯一索引,并且您在该索引上查询单个文档。 解释中的什么indexBounds告诉你,为了检索这个特定的文档,它扫描索引从这个索引的[lower,upper]边界开始,在这种情况下碰巧是相同的,因为你在查询中指定了一个文档。 nscanned = 1也验证了这一点。

如果要查看不同的边界,请尝试将指定正则表达式的查询指定为:{uri: {$regex:'^"http://dbpedia*'}}然后可能需要扫描更多文档,并且您将在explain()中获得不同的[upper,lower]界限