我有一个集合,我从中获得使用$ query的特定类型的用户 然后我需要根据user_id升序对它们进行排序并将它们限制为2000
从这些我需要max user_id,所以我按降序排序并限制为1.
但是第二种类型会忘记2000的限制,并从find()中对整个游标进行排序。
任何解决方法?
$cursor = $collection ->find($query) // too many entries
->sort(array('user_id'=>1)) // go ascending
->limit(2000) // got our limited qouta
->sort(array('user_id'=>-1)) // go descending to get max
->limit(1); // the one with max(user_id)
答案 0 :(得分:7)
你不能做一个排序,然后是一个限制,然后排序。 Cursor对象就是这样,在你通过getNext()
迭代到第一个结果之前它不会运行查询,这个结果要么手动运行,要么在foreach
循环内运行,不仅如此,sort
是只是对象的一个属性,这样做两个排序只会覆盖属性。
实现目标的最佳方式是:
$doc = $collection->find($query)->sort(array('user_id' => 1))
->skip(1999)->limit(1)->getNext();
这将始终选择组中最高user_id
(在此类末尾发生),这将产生与进行两种排序相同的结果。
答案 1 :(得分:3)
如何使用skip():
$cursor = $collection ->find($query)
->sort(array('user_id'=>1))
->limit(2000)
->skip(1999);
答案 2 :(得分:0)
排序限制排序限制方法背后的原因是什么?
你不能这样做吗
$cursor = $collection ->find($query)
->sort(array('user_id'=>-1))
->limit(1);
编辑:此外,只有应用于游标的最后sort
才有效。 (这一行出现在pymongo
docs here中,这是有道理的。)
答案 3 :(得分:0)
$doc = $collection->find($query)->sort(array('user_id' => 1))
->skip(1999)->limit(1)->getNext();
我在->skip(1999)->limit(1)
sort()
时停止工作
光标$doc
确实给了我值。我试着将它制成这个:
$doc = $collection->find($query)->sort(array('user_id' => 1))
$doc = $doc->skip(1999)->limit(1);
那很有用。也许你应该在新版本中尝试。
答案 4 :(得分:0)
this tweet是正确的。
您仍然可以达到您想要的方式。您可以使用聚合框架,因为它在其他阶段之后执行一个阶段,依此类推。
$doc = $collection->aggregate(array(
array(
'$match' => $query,
),
array(
'$sort' => array(
'user_id'=> 1
),
),
array(
'$limit' => 2000
),
array(
'$sort' => array(
'user_id'=> -1
),
),
array(
'$limit' => 1
),
));