简体   繁体   English

排序后mongo排序后限制 - 不工作

[英]mongo sort after limit after sort - Not working

I have a collection, from which i get particular type of users using $query 我有一个集合,从中我使用$ query获得特定类型的用户
Then I need sort them according to user_id ascending and limit them to 2000 然后我需要根据user_id升序对它们进行排序并将它们限制为2000

From these I need the max user_id, so I sort them in descending order and limit to 1. 从这些我需要max user_id,所以我按降序排序并限制为1。

But this second sort forgets the limit of 2000 and sorts over over the entire cursor from find(). 但是第二种类型会忘记2000的限制,并从find()中对整个游标进行排序。

Any work-around? 任何解决方法?

$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)

Your cannot do a sort and then a limit and then a sort. 你不能做一个排序,然后限制,然后排序。 The Cursor object is exactly that and it will not run the query until you iterate to the first result via getNext() which is either run manually or within a foreach loop not only that but sort is just a property of the object as such making two sorts just overwrites the property. Cursor对象就是这样,它将不会运行查询,直到您通过getNext()迭代到第一个结果, getNext()可以手动运行,也可以在foreach循环中运行,不仅如此,而sort只是对象的属性,因此使得两个排序只是覆盖属性。

The best way to achieve what your looking for is: 实现您所寻求目标的最佳方式是:

$doc = $collection->find($query)->sort(array('user_id' => 1))
       ->skip(1999)->limit(1)->getNext();

That will always pick the highest user_id (which occurs at the end in this sort) of the group, which will give off the same results as doing two sorts. 这将始终选择组中最高的user_id (在此类末尾发生),这将产生与进行两种排序相同的结果。

How about using skip(): 使用skip()怎么样:

$cursor = $collection   ->find($query)  
        ->sort(array('user_id'=>1))   
        ->limit(2000)                
        ->skip(1999);

What is the reason behind sort-limit-sort-limit approach? 排序限制排序限制方法背后的原因是什么?

Can't you just do 你不能这样做吗?

$cursor = $collection ->find($query)
            ->sort(array('user_id'=>-1))
            ->limit(1);

EDIT: Also, only the last sort applied to the cursor has an effect. 编辑:此外,只有应用于光标的最后sort才有效。 (This line is present in pymongo docs here , which makes sense.) (此行的存在pymongo文档这里 ,这是有意义的。)

I am using the following code in and latest build: 我在最新版本中使用以下代码:

$doc = $collection->find($query)->sort(array('user_id' => 1))
    ->skip(1999)->limit(1)->getNext();

It stops working when I use ->skip(1999)->limit(1) after sort() 它停止工作,当我使用->skip(1999)->limit(1)sort()

The cursor $doc does give me values . 游标$doc确实给了我值。 I tried braking it down into this: 我试着把它制成这个:

$doc = $collection->find($query)->sort(array('user_id' => 1))
$doc = $doc->skip(1999)->limit(1);

That worked. 那很有效。 May be you should try that in new versions. 也许你应该在新版本中尝试。

Answer by Sammaye is correct. Sammaye的回答是正确的。

You can still achieve the way you wanted. 你仍然可以达到你想要的方式。 You can use aggregation framework, as it executes one stage after other stage and so on. 您可以使用聚合框架,因为它在其他阶段之后执行一个阶段,依此类推。

$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
    ),
));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM