mongoDBの文字列フィールド値の長さ



String Field Value Length Mongodb



解決:

MongoDB 3.6以降の場合:

NS $ expr 演算子を使用すると、クエリ言語内で集計式を使用できるため、 $ strLenCP 次のように文字列の長さをチェックする演算子:



db.usercollection.find({'name':{'$ exists':true}、 '$ expr':{'$ gt':[{'$ strLenCP': '$ name'}、40]}})

MongoDB 3.4以降の場合:

で集約フレームワークを使用することもできます $編集 論理条件を処理できるパイプライン演算子 $ cond 演算子と特別な操作を使用します $$ KEEP 論理条件が真であるドキュメントを「保持」する、または $$プルーン 条件がfalseであったドキュメントを「削除」します。



この操作は、 $ project コレクション内のフィールドを選択し、論理条件クエリの結果を保持する新しいフィールドを作成し、その後に続くパイプライン $ match 、 それ以外で $編集 より効率的な単一のパイプラインステージを使用します。

論理条件としては、使用できる文字列集計演算子があります $ 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はそのプレフィックスから範囲を構築し、その範囲内にあるインデックスの値とのみ一致することができます。

正規表現は、キャレットで始まる場合は接頭辞式です(^)または左アンカー( A)の後に、単純な記号の文字列が続きます。たとえば、正規表現/^abc.*/は、で始まるインデックスの値とのみ照合することで最適化されますabc。

さらに、/^a/、/^a.*/、および/^a.*$/は同等の文字列と一致し、パフォーマンス特性が異なります。適切なインデックスが存在する場合、これらの式はすべてインデックスを使用します。しかし、/^a.*/、および/^a.*$/は遅いです。/ ^ a /は、プレフィックスを一致させた後、スキャンを停止できます。


とのクエリ$ where andドキュメントが多すぎると、$ exprが遅くなります。

使用する$ regexはよりもはるかに高速です$ where、$ expr。

db.usercollection.find({'name':/ ^ [ s  S] {40、} $ /、// name.length> = 40})またはdb.usercollection.find({'name':{' $ regex ':' ^ [ s  S] {40、} $ '}、// name.length> = 40})

このクエリはと同じ意味です

db.usercollection.find({'$ where': 'this.name && this.name.length> = 40'、})またはdb.usercollection.find({'name':{'$ exists':true}、 '$ expr':{'$ gte':[{'$ strLenCP': '$ name'}、40]}})

コレクションの各クエリをテストしました。

#find $ where:10529.359ms $ expr:5305.801ms $ regex:2516.124ms#count $ where:10872.006ms $ expr:2630.155ms $ regex:158.066ms 

これは、mongodbでこれを実現する方法の1つです。

db.usercollection.find({$ where: 'this.name.length<4' })