28

MongoDBで整数値を正規表現検索したい。これは可能ですか?

さまざまなフィールドでワイルドカードを使用できる*CRUDタイプのインターフェイスを構築しています。整数であるいくつかのフィールドのUIの一貫性を維持しようとしています。

検討:

> db.seDemo.insert({ "example" : 1234 });
> db.seDemo.find({ "example" : 1234 });
{ "_id" : ObjectId("4bfc2bfea2004adae015220a"), "example" : 1234 }
> db.seDemo.find({ "example" : /^123.*/ });
> 

ご覧のとおり、オブジェクトを挿入すると、値で見つけることができます。単純な正規表現を試してみると、実際にはオブジェクトが見つかりません。

ありがとう!

4

2 に答える 2

45

数値のパターンマッチを実行したい場合、mongoでそれを実行する方法は、$ where式を使用して、パターンマッチを渡すことです。

> db.test.find({ $where: "/^123.*/.test(this.example)" })
{ "_id" : ObjectId("4bfc3187fec861325f34b132"), "example" : 1234 }
于 2010-05-25T20:42:32.170 に答える
19

$whereクエリ式を評価する方法、インデックスを使用しない、クエリがユーザー入力データを使用する場合のセキュリティリスクがあるため、私はクエリ演算子を使用するのが好きではありません。

MongoDB 4.2以降$regexMatch|$regexFind|$regexFindAllでは、MongoDB4.1.9以降で利用可能なを使用$exprしてこれを行うことができます。

let regex = /123/;
  • $regexMatch$regexFind

    db.col.find({
        "$expr": {
            "$regexMatch": {
               "input": {"$toString": "$name"}, 
               "regex": /123/ 
            }
        }
    })
    
  • $regexFinAll

    db.col.find({
        "$expr": {
            "$gt": [
                { 
                    "$size": { 
                        "$regexFindAll": { 
                            "input": {"$toString": "$name"}, 
                            "regex": "123" 
                        }
                    }
                }, 
                0
            ]
        }
    })
    

MongoDB 4.0からは、演算子のラッパーである演算子を使用して整数を$toString文字列化できます。$convert

db.seDemo.aggregate([ 
    { "$redact": { 
        "$cond": [ 
            { "$gt": [ 
                { "$indexOfCP": [ 
                    { "$toString": "$example" }, 
                    "123" 
                ] }, 
                -1 
            ] }, 
            "$$KEEP", 
            "$$PRUNE" 
        ] 
    }}
])

リリース3.4以降、特定のサブストリングを含むすべてのドキュメントを取得する必要がある場合は、反復ロジック処理$redactを可能にする演算子を使用できます。。$cond$indexOfCP

db.seDemo.aggregate([ 
    { "$redact": { 
        "$cond": [ 
            { "$gt": [ 
                { "$indexOfCP": [ 
                    { "$toLower": "$example" }, 
                    "123" 
                ] }, 
                -1 
            ] }, 
            "$$KEEP", 
            "$$PRUNE" 
        ] 
    }}
])

これは以下を生成します:

{ 
    "_id" : ObjectId("579c668c1c52188b56a235b7"), 
    "example" : 1234 
}

{ 
    "_id" : ObjectId("579c66971c52188b56a235b9"), 
    "example" : 12334 
}

MongoDB 3.4より前では、ドキュメントに、数値の文字列値である別の計算フィールドを追加する必要があり$projectます。

と彼の$toLower兄弟$toUpper演算子はそれぞれ文字列を小文字と大文字に変換しますが、整数を文字列に変換するために使用できるという少し未知の機能があります。

演算子は、演算子$matchを使用して、パターンに一致するすべてのドキュメントを返します$regex

db.seDemo.aggregate(
    [ 
        { "$project": { 
            "stringifyExample": { "$toLower": "$example" }, 
            "example": 1 
        }}, 
        { "$match": { "stringifyExample": /^123.*/ } }
    ]
)

これにより、次のようになります。

{ 
    "_id" : ObjectId("579c668c1c52188b56a235b7"), 
    "example" : 1234,
    "stringifyExample" : "1234"
}

{ 
    "_id" : ObjectId("579c66971c52188b56a235b9"), 
    "example" : 12334,
    "stringifyExample" : "12334"
}

さて、あなたが望むのが特定の部分文字列を含むすべてのドキュメントを取得することである場合、これを行うためのより簡単でより良い方法は、反復論理処理$redactを可能にする演算子を使用するMongoDBの次のリリース(この記事の執筆時点)です。。$cond$indexOfCP

db.seDemo.aggregate([ 
    { "$redact": { 
        "$cond": [ 
            { "$gt": [ 
                { "$indexOfCP": [ 
                    { "$toLower": "$example" }, 
                    "123" 
                ] }, 
                -1 
            ] }, 
            "$$KEEP", 
            "$$PRUNE" 
        ] 
    }}
])
于 2016-07-30T09:12:29.017 に答える