我试图找出mongodb中使用的最佳索引:
db.articles.find({"images.url":{"$exists":true}, \
"source_id": {"$in":[ObjectId("511baf3aa56bde8e94000002"), ObjectId("511baf3aa56bde8e94000999")]}}) \
.sort({"published_at": -1})
我只想包含images.url存在的文章,所以我想知道它是否是一个稀疏索引?并且不确定要按顺序索引哪些字段,因为我已经阅读了不同的指针:
另外,在上面的例子中,我不确定source_id是否是一系列值?
我在想:
index "images.url": -1, published_at: -1, source_id: 1, {sparse: true}
但是我对于索引的最大化排他性也很不满,所以我在考虑:
index source_id: 1, "images.url": -1, published_at: -1, {sparse: true}
答案 0 :(得分:4)
如果我们有这样的集合
{ a:1, b:1, c:1 }
{ a:1, b:1, c:2 }
{ a:1, b:1, c:3 }
{ a:1, b:2, c:1 }
... // all permutations up to:
{ a:3, b:3, c:3 }
以随机顺序设想这个集合
这是({a:1,b:1,c:1})的复合指数看起来像
a: | 1 | 2 | 3 |
|-----------------+-----------------+-----------------|
b: | 1 | 2 | 3 | 1 | 2 | 3 | 1 | 2 | 3 |
|-----+-----+-----+-----+-----+-----+-----+-----+-----|
c: |1|2|3|1|2|3|1|2|3|1|2|3|1|2|3|1|2|3|1|2|3|1|2|3|1|2|3|
对于每一个你拥有它的所有b的所有c依次,好吗?
对于查询: db.xx.find({a:2})。sort({b:1}),您可以看到b元素在a =下面的顺序2;索引将用于排序 - explain()中的“scanAndOrder”:false 。如果您的查询是 db.xx.find({a:2,c:{$ in:[1,3]}}),则会发生同样的情况。排序({b:1}) < / p>
但是这个: db.xx.find({a:{$ in:[1,3]}})。sort({b:1})。explain()会告诉你“scanAndOrder”:true ,这意味着索引不用于排序(虽然它用于查询) - 从上面的模式可以看出,“b”不是按顺序排列的对于a = [1,3]。
这就是为什么索引的有效序列是:
(1) exact matches (only one!)
(2) sort criteria
(3) matches that point to more than one document
在你的情况下,没有完全匹配;两个查询都返回多个文档。让我们在我们的例子中试试这个:
<强> db.xx.find({一个:{$中:[1,3]},B:{$中:[1,3]}})排序({C:1})。。 explain():使用索引进行查询,但不进行排序,它会扫描15并返回12个对象。
<强> db.xx.find({B:{$中:[1,3]},C:{$中:[1,3]}})排序({一个:1})。。 explain():使用索引进行查询和排序,但扫描21并返回12个对象。
哪一个更好?这取决于您的使用案例。如果您的查找通常会返回许多文档,那么使用索引可以更有效地使用索引 - 但如果它通常只返回少数(在众多中),那么您可能更喜欢更有效的扫描。尝试一下,看看使用explain()
有什么好处这有帮助吗?
问候
罗纳德
P.S。我用它来创建示例集合:
[1,2,3].forEach(function(a){
[1,2,3].forEach(function(b){
[1,2,3].forEach(function(c){
db.xx.insert({a:a,b:b,c:c});
})
})
})