mongo сортировать после предела после сортировки – Не работает

У меня есть коллекция, из которой я получаю определенный тип пользователей, используя $ 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) 

Вы не можете сделать своего рода, а затем лимит, а затем сорт. Объект Cursor точно такой, и он не будет запускать запрос до тех пор, пока вы не перейдете к первому результату через getNext() который либо запускается вручную, либо внутри цикла foreach не только, но и sort – это просто свойство объекта, поскольку оно делает два sorts просто перезаписывает свойство.

Лучший способ добиться того, что вы ищете:

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

Это всегда будет выбирать самый высокий user_id (который встречается в конце этого типа) группы, что даст те же результаты, что и два вида.

Как насчет использования skip ():

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

В чем причина подхода к методу сортировки-лимита-сортировки?

Разве ты не можешь просто сделать

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

EDIT: Также действует только последний sort применяемый к курсору. (Эта строка присутствует здесь в pymongo docs, что имеет смысл.)

Я использую следующий код в php5 и последней версии mongodb :

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

Это сработало. Может быть, вы должны попробовать это в новых версиях.

Ответ Sammaye верен.

Вы все еще можете достичь того, чего хотите. Вы можете использовать структуру агрегации, поскольку она выполняет один этап после другого этапа и так далее.

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