我在mongodb上有大量文档,这是一个虚拟插入
array (
'_id' => new MongoId("51a449866803fa680a000002"),
'a' => 'dweddwe',
'b' => 'asdasdad',
'c' =>
array (
'0' => 'car',
),
'u' => '1',
'x' =>
array (
'0' => '51a0c0356803fa890a000003',
'1' => '51a0c0356803fa890a000003',
),
'y' => 'merto',
)
我的mongo数据库中插入的文档超过100个,问题是,当我使用此代码和索引(如x_1__id_1
或其他任何方式)时,我总是得到[scanAndOrder] => 1
,我有不知道可能是什么问题或解决方案,我怎样才能以有效的方式对其进行排序?谢谢你:))
$m->cars->post->find(array("x" => array('$in' => $mendor["t"])))->limit(10)->sort(array("_id" => -1))->explain();
这是$ mendor [“t”],
't' =>
array (
'0' => '519f2de16803fabd0d000001',
'1' => '51a0bf996803fa890a000001',
'2' => '519f2db96803fad20d000001',
'3' => '519f1cc56803fa960d000001',
),
答案 0 :(得分:0)
Compund索引不能用于反向排序,但是如果你在$ mendor [“t”]中有一个真正的列表,那么在这种情况下它不会有任何帮助。 我用简单的文档制作了一个名为t的测试集合,如:
{ "_id" : ObjectId("51a4c2c75e0733e8428ab2c0"), "x" : [ 1, 2, 3, 4 ] }
{ "_id" : ObjectId("51a4c2c95e0733e8428ab2c1"), "x" : [ 1, 2, 3, 6 ] }
{ "_id" : ObjectId("51a4c2cd5e0733e8428ab2c2"), "x" : [ 1, 4, 3, 6 ] }
我创建了索引:x_1__id_1
对于查询:
db.t.find({x:3}).hint("x_1__id_1").sort({_id:1}).explain()
{
"cursor" : "BtreeCursor x_1__id_1",
"isMultiKey" : true,
"n" : 14,
"nscannedObjects" : 14,
"nscanned" : 14,
"nscannedObjectsAllPlans" : 14,
"nscannedAllPlans" : 14,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 0,
"indexBounds" : {
"x" : [
[
3,
3
]
],
"_id" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
]
},
"server" : ""
}
所以它可以让你的查询工作,但是:
db.t.find({x:{$in:[3,4]}}).hint("x_1__id_1").sort({_id:1}).explain()
{
"cursor" : "BtreeCursor x_1__id_1 multi",
"isMultiKey" : true,
"n" : 16,
"nscannedObjects" : 28,
"nscanned" : 28,
"nscannedObjectsAllPlans" : 28,
"nscannedAllPlans" : 28,
"scanAndOrder" : true,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 0,
"indexBounds" : {
"x" : [
[
3,
3
],
[
4,
4
]
],
"_id" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
]
},
"server" : ""
}
这是合理的,而使用的多键索引是作为分离的索引键存储在数组中的值。请参阅文档:http://docs.mongodb.org/manual/core/indexes/#multikey-indexes
因此,从不同的键收集的不同部分将由引擎合并而不是分类。如果您使用的标准与我的第一个查询类似,那么只需搜索一个数组而不是数组。比它将scanAndOrder:false。可能你必须创建一个x_1_ id -1索引。
有一种解决方法,但它有点难看。如果对查询使用or子句,则或者列表的每个部分将单独使用索引用法。因此,不要使用in:[]条件,而是使用or:[]并在$ mendor [“t”]数组中定义尽可能多的不同查询。在mongoshell没有用,但我确信它应该,也许我错过了一些东西。
答案 1 :(得分:0)
x,_id上有复合索引。 _id的顺序不是绝对的,而是在x值的上下文中。在您的查询中,您正在为特定的x值选择一组文档,然后按_id排序。因此,为了获得订单,它必须基于_id值对结果进行实际排序,而不是仅使用索引顺序。这就是你看到的扫描和命令是真的。希望这会有所帮助。