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/
プレフィックスを一致させた後、スキャンを停止できます。