集計フレームワークの$skipと$limit 質問する

集計フレームワークの$skipと$limit 質問する

文書を読んでみると、次のような記述がありました。

パイプラインで $sort が $limit の直前にある場合、$sort 操作は進行中に上位 n 件の結果のみを保持します。ここで n は指定された制限であり、MongoDB は n 件の項目のみをメモリに格納する必要があります。allowDiskUse が true で、n 件の項目が集約メモリ制限を超える場合でも、この最適化は適用されます。

もしこれが正しければ、$sortと$limitを一緒に使用する場合にのみ適用されます。

db.coll.aggregate([
    ...,
    {$sort: ...},
    {$limit: limit},
    ...
]);

しかし、ほとんどの場合、

db.coll.aggregate([
    ...,
    {$sort: ...},
    {$skip: skip},
    {$limit: limit},
    ...
]);

質問1: ここで $skip を使用すると、上記のルールは適用されないということですか?

この質問をするのは、理論的にはMongoDBがトップを計算することができるからです。レコードをソートし、上位のみをソートすることでパフォーマンスを向上させます記録。しかし、これに関する文書は見つかりませんでした。そして、このルールが適用されない場合は、

質問2: パフォーマンスを向上させるには、クエリを次のように変更する必要がありますか?

db.coll.aggregate([
    ...,
    {$sort: ...},
    {$limit: skip + limit},
    {$skip: skip},
    {$limit: limit},
    ...
]);

編集: 私のユースケースを説明すると、上記の質問の意味がより明確になると思います。私は、MongoDB 2.6 が提供するテキスト検索機能を使用して製品を検索しています。ユーザーが「赤」などの非常に一般的なキーワードを入力すると、返される結果が多すぎるのではないかと心配しています。そのため、この結果を生成するためのより良い方法を探しています。

編集2: 上記の最後のコードは、

db.coll.aggregate([
    ...,
    {$sort: ...},
    {$limit: skip + limit},
    {$skip: skip},
    ...
]);

したがって、このフォームを常に使用してトップnルールが適用されます。

ベストアンサー1

ここで取り上げているのはテキスト検索クエリなので、最も最適な形式は次のようになります。

db.collection.aggregate([
    { 
       "$match": {
               "$text": { "$search": "cake tea" }
    }
    },
    { "$sort": { "score": { "$meta": "textScore" } } },
    { "$limit": skip + limit },
    { "$skip": skip }
])

上位の「ソート」結果からのメモリ予約の根拠は、いわばそれ自身の「制限」内でのみ機能し、いくつかの妥当な「ページ」のデータを超えるものには最適ではありません。

メモリ消費量が妥当な範囲を超えると、追加ステージはプラスよりもマイナスの影響を与える可能性が高くなります。

これらは、現在の形式で MongoDB が利用できるテキスト検索機能の実際的な制限です。ただし、より詳細でより高いパフォーマンスが必要な場合は、多くの SQL「フルテキスト」ソリューションの場合と同様に、外部の「専用」テキスト検索ソリューションを使用する方が適切です。

おすすめ記事