Php 在多键排序时,如何进行扫描和排序0
我在mongodb上有很多文档,这是一个虚拟插入Php 在多键排序时,如何进行扫描和排序0,php,mongodb,Php,Mongodb,我在mongodb上有很多文档,这是一个虚拟插入 array ( '_id' => new MongoId("51a449866803fa680a000002"), 'a' => 'dweddwe', 'b' => 'asdasdad', 'c' => array ( '0' => 'car', ), 'u' => '1', 'x' => array ( '0' => '51a0c035680
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
或以任何其他方式使用这些代码和索引时,我总是得到[scanander]=>1
,我不知道可能是什么问题或解决方案,如何有效地对其进行排序?谢谢:)
这是$mendor[“t”]
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" : ""
}
这在某种程度上是合理的,因为所使用的多键索引将数组中的值存储为单独的索引键。见文件:
因此,引擎将合并从不同键收集的不同部分,然后进行排序。如果使用与我的第一个查询类似的条件,那么只需搜索一个值而不是数组。比它所能扫描的还要多:错。也许你必须做一个x_1_id-1索引
有一个解决办法,但有点难看。如果对查询使用or子句,则or列表的每个部分都将单独使用索引用法。因此,不要使用in:[]条件,而是使用or:[]并定义尽可能多的不同查询,就像$mendor[“t”]数组中的值一样多。在mongoshell中不起作用,但我相信它应该起作用,也许我遗漏了什么。在x上有一个复合索引,\u id。id的顺序不是绝对的,而是在x值的上下文中。在查询中,您为特定的x值选择一组文档,然后仅按_id排序。因此,为了获得顺序,它必须实际根据_id值排序结果,而不是仅使用索引顺序。这就是你们所看到的,扫描和排序是真实的。希望这有帮助。如何合并密钥?如何添加排序阶段?谢谢你的回答:)对不起,我说错了。没有办法做你喜欢做的。我只是喜欢用这个合并的东西来写,它将由数据库引擎来完成,并且如果使用$in和长度超过1个元素的数组,它将无法使用索引进行排序。我根据这个编辑我的答案。好吧,这对我来说不好:)但是谢谢你,你的解释很好:)假设我有500个值,会不会有问题?谢谢你的答案:)$或者不按_id:)排序我会在另一个模式中进行,并尝试更改itOk,但它与基于范围的查询的情况有什么不同?这也表明了同样的现象。我猜也是出于同样的原因。mongo是否利用了_ID是按顺序排列的部分,或者只是在没有任何假设的情况下对它们进行排序?
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" : ""
}