mongo sort after limit after sort - Not working

后端 未结 5 1822
余生分开走
余生分开走 2020-12-18 02:15

I have a collection, from which i get particular type of users using $query
Then I need sort them according to user_id ascending and limit them to 2000

From t

相关标签:
5条回答
  • 2020-12-18 02:39

    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.

    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.

    0 讨论(0)
  • 2020-12-18 02:42

    How about using skip():

    $cursor = $collection   ->find($query)  
            ->sort(array('user_id'=>1))   
            ->limit(2000)                
            ->skip(1999);
    
    0 讨论(0)
  • 2020-12-18 02:44

    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. (This line is present in pymongo docs here, which makes sense.)

    0 讨论(0)
  • 2020-12-18 02:46

    I am using the following code in php5 and mongodb 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()

    The cursor $doc does give me values . 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.

    0 讨论(0)
  • 2020-12-18 02:51

    Answer by Sammaye is correct.

    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
        ),
    ));
    
    0 讨论(0)
提交回复
热议问题