文書を読んでみると、次のような記述がありました。
パイプラインで $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「フルテキスト」ソリューションの場合と同様に、外部の「専用」テキスト検索ソリューションを使用する方が適切です。