0

我在 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 '}).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 文档,这就是为什么我们在 . 中获得相同 uri 索引的两个条目。indexBounds这是什么意思?这发生在我查找的任何 URI 上。

更新

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

4

2 回答 2

3

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

你也可以做类似的事情

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

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

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

于 2015-04-10T10:45:25.360 回答
1

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

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

于 2015-04-10T10:52:54.740 回答