2012-02-21 41 views
1

我知道Multikeys允许您有效地查找具有数组作为字段的对象,其中该数组中存在特定的值。在MongoDB中,你可以索引一个字段来查找在数组中没有值的对象吗?

例如,你可以存储对象:

{ 
    "ar":["book","cat"] 
} 

,然后提供的“AR”字段建立索引,你可以说:

db.blah.find({"ar":"cat"}) 

它将有效地发现上面目的。

然而,会是这样的工作:

db.blah.find({"ar":{$not : "cat"}}) 

在这里,我想找到这里的“AR”阵列不包含“猫”中的所有对象。此查询是否有效,如果有效,它会有效吗? (即它会使用“ar”字段上的索引吗?)

回答

1

如果你看看这个MongoDB server issue,答案是“它可以使用索引”。

但是,使用$not运算符时,使用索引通常效率不高。如果'cat'出现在2%的条目中,则仍然需要读取98%的数据。此时,您可能只需一次读取一个条目的整个数据集。

+0

这个想法是,“猫”会出现在除了一些条目之外的所有条目中。话虽如此,你链接到的问题只涉及一个简单的“不等于”字段,它并不是指数组中的“不包含”。 – sanity 2012-02-22 01:21:52

1

$ not操作符未按照您暗示的方式使用,它是一个元操作符,用于否定仅检查另一个操作符。我想你实际上意味着使用$ NE:

db.blah.find({ "ar" : { $ne : "cat"}}) 

如果你这样做,你有“AR”,然后索引,因为它是你将不得不扫描几乎所有文档的消极比赛在索引中检查每一个 - 这实际上比单独扫描表的效率低,因为您必须执行索引加载/扫描,然后将所有数据都提取以返回结果。

如果这足够重要且足够频繁以避免发生这种情况,那么为什么不添加一个简单的字段是真/假(或在我的示例中为0/1)来测试“猫”领域。在这里,我将这样的字段添加到现有的数据集,我建议将它添加上创建或修改,以在将来添加“猫”虽然 - 避免批量操作通常是一个好主意:

db.blah.update({ "ar" : "cat"}, { $set : {"cat_test" : 1 } }, true, true) 
db.blah.update({ "ar" : {$ne : "cat"}}, { $set : {"cat_test" : 0 } }, true, true) 
db.blah.ensureIndex({ "cat_test" : 1 }) 

现在你可以运行类似于:

db.blah.find({ "cat_test" : 0 }) 

这将有效地使用索引。不管这是否值得,取决于你的数据使用情况和你的型号,当然​​是

相关问题