我的test
数据库中有这个test
集合。
[test] 2014-02-11 18:01:33.970 >>> db.test.find ();
{ "_id" : ObjectId("52faa8a695fa10cc7d2b7908"), "x" : 1 }
{ "_id" : ObjectId("52faa8ab95fa10cc7d2b7909"), "x" : 5 }
{ "_id" : ObjectId("52faa8ad95fa10cc7d2b790a"), "x" : 15 }
{ "_id" : ObjectId("52faa8b095fa10cc7d2b790b"), "x" : 25 }
{ "_id" : ObjectId("52faa8b795fa10cc7d2b790c"), "x" : [ 5, 25 ] }
如果我使用
在x字段上创建升序索引[test] 2014-02-11 18:01:50.615 >>> db.test.createIndex({x : 1});
然后这个查找查询工作正常并返回预期结果:
[test] 2014-02-11 18:01:48.72 >>> db.test.find ( { x : {$gt: 10, $lt: 20} } ).min({x:10}).max({x:20});
{ "_id" : ObjectId("52faa8ad95fa10cc7d2b790a"), "x" : 15 }
[test] 2014-02-11 18:01:50.615 >>>
如果删除升序索引,则为Buf,然后使用
创建降序索引[test] 2014-02-11 18:01:50.615 >>> db.test.createIndex({x : -1});
然后相同的查询返回此错误:
error: {
"$err" : "no index found for specified keyPattern: {} min: { x: 10.0 } max: { x: 20.0 }",
"code" : 10367
}
我期待MongoDB会在这里返回相同的文档:
{ "_id" : ObjectId("52faa8ad95fa10cc7d2b790a"), "x" : 15 }
这对我来说听起来不合逻辑 这是为什么?为什么MongoDB无法在x上使用该降序索引?
答案 0 :(得分:3)
这对我有用:
> db.h.insert({x:15})
> db.h.createIndex({x:-1})
> db.h.find().min({x:20}).max({x:10})
{ "_id" : ObjectId("52fb6930253ac3dcf43b27f5"), "x" : 15 }
您的索引可能有问题。
这种方法起作用的原因是因为索引是另一种方式。
想象一下你在它的头上转了一个列表,min和max有效地说是获得该列表的范围,其中min为10且max为20.但是由于列表是颠倒的,所以该范围不再存在。相反,必须反转范围以匹配列表。
答案 1 :(得分:1)
要回答你的问题,这根本不奇怪(如果你真的看看你在做什么,你好像在问很多问题,说明“奇怪”的行为)。
正如您所说将您的索引的顺序更改为降序。因此,让我们分阶段查看查询结果:
> db.test.find ( { x : {$gt: 10, $lt: 20} } )
{ "_id" : ObjectId("52faa8b795fa10cc7d2b790c"), "x" : [ 5, 25 ] }
{ "_id" : ObjectId("52faa8ad95fa10cc7d2b790a"), "x" : 15 }
因此,您的第一个结果是唯一符合您条件的文档。那么让我们看一下下一阶段以及解释的输出:
> db.test.find ( { x : {$gt: 10, $lt: 20} } ).min({x :10})
{ "_id" : ObjectId("52faa8b795fa10cc7d2b790c"), "x" : [ 5, 25 ] }
> db.test.find ( { x : {$gt: 10, $lt: 20} } ).min({x :10}).explain()
{
"cursor" : "BtreeCursor x_-1",
"isMultiKey" : true,
"n" : 1,
"nscannedObjects" : 3,
"nscanned" : 3,
"nscannedObjectsAllPlans" : 3,
"nscannedAllPlans" : 3,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 0,
"indexBounds" : {
"start" : {
"x" : 10
},
"end" : {
"x" : {
"$minElement" : 1
}
}
},
"server" : "ubuntu:27017"
}
在这里,我们可以看到包含 x 中数组值的行的结果。这是您需要查看解释输出中显示的indexBounds
的重要部分。您可以看到边界从10开始,这是您的请求,并以数组元素的最小结果结束。尽管您在文档中缺乏预测,但实际上已经给出了答案, 5 。
因此,当您再次开始修改,查找indexBounds之外的结果时,查询将 boom 。你搞砸了,并要求一些不存在的东西。
现在,如果您期待将结果取回:
{ "_id" : ObjectId("52faa8b795fa10cc7d2b790c"), "x" : [ 25 ] }
答案是,事情就是这样。如上所述,您已经在第一个 min 操作中减少了该设置。已经完成了。