7

コレクションがあり、そこから $query を使用して特定のタイプのユーザーを取得します
次に、user_id の昇順に従ってそれらを並べ替え、2000 に制限する必要があります

これらから最大の user_id が必要なので、降順で並べ替えて 1 に制限します。

しかし、この 2 番目の並べ替えでは、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)
4

5 に答える 5

7

並べ替え、制限、並べ替えを行うことはできません。Cursor オブジェクトはまさにそれであり、getNext()手動で実行されるかforeachループ内で実行される最初の結果に反復するまでクエリを実行しません。それだけでなくsort、オブジェクトのプロパティであるため、2 つの並べ替えを行うとプロパティが上書きされます。 .

あなたが探しているものを達成するための最良の方法は次のとおりです。

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

これは常にuser_idグループの最高 (このソートの最後に発生する) を選択し、2 つのソートを実行するのと同じ結果をもたらします。

于 2013-01-20T14:45:41.247 に答える
3

スキップ()を使用するのはどうですか:

$cursor = $collection   ->find($query)  
        ->sort(array('user_id'=>1))   
        ->limit(2000)                
        ->skip(1999);
于 2013-01-20T11:52:05.693 に答える
0

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
    ),
));
于 2016-09-02T12:15:56.873 に答える
0

sort-limit-sort-limit アプローチの背後にある理由は何ですか?

できませんか?

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

編集:また、カーソルに最後sortに適用されたものだけが効果があります。(この行はpymongodocs hereにあり、意味があります。)

于 2013-01-20T11:11:56.570 に答える
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);

それはうまくいきました。新しいバージョンでそれを試す必要があるかもしれません。

于 2014-11-07T08:29:32.200 に答える