web-dev-qa-db-ja.com

Mongodbで大文字と小文字を区別しないクエリを作成するにはどうすればよいですか?

var thename = 'Andrew';
db.collection.find({'name':thename});

大文字と小文字を区別しないでクエリを実行するにはどうすればよいですか? 「アンドリュー」でも結果を見つけたい。

72
user847495

Chris Fulstowのソリューションは動作します(+1)が、特にコレクションが非常に大きい場合、効率的ではない可能性があります。非ルート正規表現(正規表現を文字列の先頭に固定する^で始まらないもの)、および大文字と小文字を区別しないためにiフラグを使用するものは、インデックスを使用しません。それらが存在します。

考えられる代替オプションは、データを非正規化して、nameフィールドの小文字バージョンを、たとえばname_lowerとして保存することです。次に、次のような大文字と小文字を区別しない完全一致を効率的に照会できます(特にインデックスが作成されている場合)。

db.collection.find({"name_lower": thename.toLowerCase()})

または、次のようにプレフィックス一致(ルート化された正規表現)を使用します。

db.collection.find( {"name_lower":
    { $regex: new RegExp("^" + thename.toLowerCase(), "i") } }
);

これらのクエリは両方ともname_lowerのインデックスを使用します。

103
dcrosta

この場合、大文字と小文字を区別しない 正規表現 を使用する必要があります。

db.collection.find( { "name" : { $regex : /Andrew/i } } );

thename変数から正規表現パターンを使用するには、新しい RegExp オブジェクトを作成します。

var thename = "Andrew";
db.collection.find( { "name" : { $regex : new RegExp(thename, "i") } } );

更新:完全に一致させるには、正規表現"name": /^Andrew$/i。 Yannick L.に感謝.

67
Chris Fulstow

このように解決しました。

 var thename = 'Andrew';
 db.collection.find({'name': {'$regex': thename,$options:'i'}});

「大文字と小文字を区別しない完全一致」でクエリする場合は、次のようにできます。

var thename =  '^Andrew$';
db.collection.find({'name': {'$regex': thename,$options:'i'}});
27
RIPAN

MongoDB 3.4には、大文字と小文字を区別しない本当のインデックスを作成する機能が含まれています。これにより、大規模なデータセットでの大文字と小文字を区別しない検索の速度が劇的に向上します。これは、強度2の照合を指定することにより作成されます。

おそらく最も簡単な方法は、データベースに照合順序を設定することです。次に、すべてのクエリがその照合を継承し、それを使用します。

db.createCollection("cities", { collation: { locale: 'en_US', strength: 2 } } )
db.names.createIndex( { city: 1 } ) // inherits the default collation

このようにすることもできます:

db.myCollection.createIndex({city: 1}, {collation: {locale: "en", strength: 2}});

そして、次のように使用します:

db.myCollection.find({city: "new york"}).collation({locale: "en", strength: 2});

これにより、「ニューヨーク」、「ニューヨーク」、「ニューヨーク」などの名前の都市が返されます。

詳細情報: https://jira.mongodb.org/browse/SERVER-9

6
user3413723

数時間前にこの問題を解決しました。

var thename = 'Andrew'
db.collection.find({ $text: { $search: thename } });
  • この方法でクエリを実行すると、大文字と小文字の区別と分音記号の区別がデフォルトでfalseに設定されます。

Andrewのユーザーオブジェクトから必要なフィールドを次のように選択することで、さらに拡張することもできます。

db.collection.find({ $text: { $search: thename } }).select('age height weight');

リファレンス: https://docs.mongodb.org/manual/reference/operator/query/text/#text

5
Briant Anthony
  1. Mongoose(およびNode)では、これが機能しました:

    • User.find({ email: /^[email protected]$/i })

    • _User.find({ email: new RegExp(_ `^ $ {emailVariable} $`、 'i')})

  2. MongoDBでは、これは機能しました。

両方の行は大文字と小文字を区別しません。 DB内の電子メールは_[email protected]_である可能性があり、両方の行は引き続きDB内のオブジェクトを検出します。

同様に、_/^[email protected]$/i_を使用しても、DB内で電子メール:_[email protected]_を見つけることができます。

4
Raymond Gan

大文字と小文字を区別しない文字列を検索するには、これを使用します。

var thename = "Andrew";
db.collection.find({"name":/^thename$/i})
2
Pranit

大文字と小文字を区別しないリテラル文字列を見つけるには:

正規表現の使用(推奨)

_db.collection.find({
    name: {
        $regex: new RegExp('^' + name.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') + '$', 'i')
    }
});
_

小文字のインデックスの使用(高速)

_db.collection.find({
    name_lower: name.toLowerCase()
});
_

正規表現は、リテラル文字列の照合よりも低速です。ただし、小文字フィールドを追加すると、コードの複雑さが増します。疑わしい場合は、正規表現を使用してください。明示的に小文字のフィールドを使用することをお勧めします。フィールドを置き換えることができる場合、つまり、そもそも大文字小文字を気にしない場合のみです。

正規表現の前に名前をエスケープする必要があることに注意してください。ユーザー入力のワイルドカードが必要な場合は、エスケープ後に.replace(/%/g, '.*')を追加して、「a%」と一致して「a」で始まるすべての名前を検索できるようにします。

2
Yeti

次のクエリは、必要な文字列insensitiveにドキュメントを検索し、さらにグローバルに出現します

db.collection.find({name:{
                             $regex: new RegExp(thename, "ig")
                         }
                    },function(err, doc) {
                                         //Your code here...
                  });
1
prodeveloper

Case Insensitive Indexesを使用できます:

次の例では、デフォルトの照合なしでコレクションを作成し、大文字と小文字を区別しない照合で名前フィールドにインデックスを追加します。 nicodeの国際コンポーネント

/*
* strength: CollationStrength.Secondary
* Secondary level of comparison. Collation performs comparisons up to secondary * differences, such as diacritics. That is, collation performs comparisons of 
* base characters (primary differences) and diacritics (secondary differences). * Differences between base characters takes precedence over secondary 
* differences.
*/
db.users.createIndex( { name: 1 }, collation: { locale: 'tr', strength: 2 } } )

インデックスを使用するには、クエリで同じ照合を指定する必要があります。

db.users.insert( [ { name: "Oğuz" },
                            { name: "oğuz" },
                            { name: "OĞUZ" } ] )

// does not use index, finds one result
db.users.find( { name: "oğuz" } )

// uses the index, finds three results
db.users.find( { name: "oğuz" } ).collation( { locale: 'tr', strength: 2 } )

// does not use the index, finds three results (different strength)
db.users.find( { name: "oğuz" } ).collation( { locale: 'tr', strength: 1 } )

または、デフォルトの照合を使用してコレクションを作成できます。

db.createCollection("users", { collation: { locale: 'tr', strength: 2 } } )
db.users.createIndex( { name : 1 } ) // inherits the default collation
1
Gencebay D.