MongoDB 3.6以降の場合:
$expr 演算子を使用すると、クエリ言語内で集計式を使用できるため、 $strLenCPの使用を活用できます。 次のように文字列の長さを確認する演算子:
db.usercollection.find({
"name": { "$exists": true },
"$expr": { "$gt": [ { "$strLenCP": "$name" }, 40 ] }
})
MongoDB 3.4以降の場合:
$redactで集計フレームワークを使用することもできます $condを使用して論理条件を処理できるパイプライン演算子 演算子を使用し、特別な操作を使用します $$KEEP 論理条件が真または$$PRUNEであるドキュメントを「保持」する 条件がfalseであったドキュメントを「削除」します。
この操作は、 $projectを使用する場合と似ています。 コレクション内のフィールドを選択し、論理条件クエリとそれに続く $matchの結果を保持する新しいフィールドを作成するパイプライン 、ただし $redact より効率的な単一のパイプラインステージを使用します。
論理条件としては、 $strLenCPを使用できる文字列集計演算子があります。 文字列の長さをチェックする演算子。長さが$gtの場合 指定された値の場合、これは真の一致であり、ドキュメントは「保持」されます。それ以外の場合は、「プルーニング」されて破棄されます。
上記の概念を示す次の集約操作を実行することを検討してください。
db.usercollection.aggregate([
{ "$match": { "name": { "$exists": true } } },
{
"$redact": {
"$cond": [
{ "$gt": [ { "$strLenCP": "$name" }, 40] },
"$$KEEP",
"$$PRUNE"
]
}
},
{ "$limit": 2 }
])
$whereを使用する場合 、括弧なしでクエリを試してください:
db.usercollection.find({$where: "this.name.length > 40"}).limit(2);
より良いクエリは、フィールドの存在を確認してから長さを確認することです:
db.usercollection.find({name: {$type: 2}, $where: "this.name.length > 40"}).limit(2);
または:
db.usercollection.find({name: {$exists: true}, $where: "this.name.length >
40"}).limit(2);
MongoDBは$where以外を評価します $whereの前のクエリ操作 式と非$where クエリステートメントはインデックスを使用できます。はるかに優れたパフォーマンスは、文字列の長さを別のフィールドとして格納してから、インデックスを作成したり検索したりできるようにすることです。 $whereを適用する それに比べてはるかに遅くなります。 JavaScript式と$whereを使用することをお勧めします 他の方法でデータを構造化できない場合、またはデータの小さなサブセットを処理している場合の最後の手段としての演算子。
$whereの使用を回避する別のより高速なアプローチ 演算子は$regexです オペレーター。
db.usercollection.find({"name": {"$type": 2, "$regex": /^.{41,}$/}}).limit(2);
注 -ドキュメントから :
フィールドにインデックスが存在する場合、MongoDBは正規表現をインデックスの値と照合します。これは、コレクションスキャンよりも高速です。正規表現が「プレフィックス式」である場合、さらに最適化が行われる可能性があります。これは、すべての潜在的な一致が同じ文字列で始まることを意味します。これにより、MongoDBはそのプレフィックスから「範囲」を構築し、その範囲内にあるインデックスの値とのみ一致することができます。
正規表現は、acaret
(^)で始まる場合、「プレフィックス式」です。 または左アンカー(\A)、その後に一連のsimplesymbolsが続きます。たとえば、正規表現/^abc.*/abcで始まるインデックスの値とのみ照合することで最適化されます 。さらに、
/^a/, /^a.*/,および/^a.*$/同等の文字列と一致すると、パフォーマンス特性が異なります。適切なインデックスが存在する場合、これらの式はすべてインデックスを使用します。ただし、/^a.*/、および/^a.*$/遅いです。/^a/プレフィックスを一致させた後、スキャンを停止できます。