例:
> db.stuff.save({"foo":"bar"});
> db.stuff.find({"foo":"bar"}).count();
1
> db.stuff.find({"foo":"BAR"}).count();
0
例:
> db.stuff.save({"foo":"bar"});
> db.stuff.find({"foo":"bar"}).count();
1
> db.stuff.find({"foo":"BAR"}).count();
0
正規表現を使用できます。
あなたの例では、次のようになります。
db.stuff.find( { foo: /^bar$/i } );
ただし、値を見つけるたびに追加のコストが発生するのではなく、途中で値を小文字化 (または大文字化) することもできます。明らかに、これは人の名前などでは機能しませんが、タグのようなユースケースではうまくいきません。
アップデート:
元の回答は廃止されました。Mongodb は、多くの機能を備えた高度な全文検索をサポートするようになりました。
元の答え:
正規表現の大文字と小文字を区別しない /i を使用した検索は、mongodb がインデックスで検索できないことを意味するため、大きなデータセットに対するクエリには時間がかかることに注意してください。
小さなデータセットであっても、あまり効率的ではありません。クエリが保証するよりもはるかに大きな CPU ヒットが発生します。これは、スケーリングを達成しようとしている場合に問題になる可能性があります。
別の方法として、大文字のコピーを保存して、それに対して検索することもできます。たとえば、大文字と小文字が混在するユーザー名を持つ User テーブルがありますが、ID はユーザー名の大文字のコピーです。これにより、大文字と小文字を区別する複製が不可能になり (「Foo」と「foo」の両方を持つことは許可されません)、id = username.toUpperCase() で検索して、大文字と小文字を区別しないユーザー名の検索を取得できます。
メッセージ本文など、フィールドが大きい場合、データの複製はおそらく適切なオプションではありません。その場合、Apache Lucene のような無関係なインデクサーを使用するのが最善の選択肢だと思います。
MongoDB 3.4 以降では、大文字と小文字を区別しない高速検索を実行するための推奨される方法は、Case Insensitive Indexを使用することです。
私は創業者の 1 人に個人的にメールを送り、これを機能させてもらいました。彼はそれを実現しました! これは2009 年以降の JIRA の問題であり、多くの人がこの機能を要求しています。仕組みは次のとおりです。
大文字と小文字を区別しないインデックスは、1 または 2 の強度で照合を指定することによって作成されます。大文字と小文字を区別しないインデックスは、次のように作成できます。
db.cities.createIndex(
{ city: 1 },
{
collation: {
locale: 'en',
strength: 2
}
}
);
コレクションを作成するときに、コレクションごとにデフォルトの照合を指定することもできます。
db.createCollection('cities', { collation: { locale: 'en', strength: 2 } } );
どちらの場合でも、大文字と小文字を区別しないインデックスをfind
使用するには、インデックスまたはコレクションの作成時に使用した操作で同じ照合順序を指定する必要があります。
db.cities.find(
{ city: 'new york' }
).collation(
{ locale: 'en', strength: 2 }
);
これは、「New York」、「new york」、「New york」などを返します。
この場合、全文検索の使用を提案する回答は間違っています(そして潜在的に危険です)。質問は、大文字と小文字を区別しないクエリを作成することに関するものでした。たとえば、全文検索クエリではなく、一致username: 'bill'
するBILL
orなどです。Bill
bill
Bills
billed
正規表現を使用することを提案する回答は遅いです。インデックスを使用しても、ドキュメントには次のように記載されているためです。
「大文字と小文字を区別しない正規表現クエリは、通常、インデックスを効果的に使用できません。$regex 実装は照合を認識せず、大文字と小文字を区別しないインデックスを利用できません。」
$regex
回答は、ユーザー入力インジェクションのリスクも伴います。
前の例は次の点に注意してください。
db.stuff.find( { foo: /bar/i } );
barを含むすべてのエントリがクエリ ( bar1、barxyz、openbar ) と一致するようになります。認証関数でのユーザー名検索には非常に危険です ...
次のように適切な正規表現構文を使用して、検索語のみに一致させる必要がある場合があります。
db.stuff.find( { foo: /^bar$/i } );
正規表現の構文ヘルプについては、 http://www.regular-expressions.info/を参照してください。
db.company_profile.find({ "companyName" : { "$regex" : "Nilesh" , "$options" : "i"}});
TL;DR
正規表現を使用しない
自然に行き、mongodbの組み込みのインデックス作成、検索を使用します
db.articles.insert(
[
{ _id: 1, subject: "coffee", author: "xyz", views: 50 },
{ _id: 2, subject: "Coffee Shopping", author: "efg", views: 5 },
{ _id: 3, subject: "Baking a cake", author: "abc", views: 90 },
{ _id: 4, subject: "baking", author: "xyz", views: 100 },
{ _id: 5, subject: "Café Con Leche", author: "abc", views: 200 },
{ _id: 6, subject: "Сырники", author: "jkl", views: 80 },
{ _id: 7, subject: "coffee and cream", author: "efg", views: 10 },
{ _id: 8, subject: "Cafe con Leche", author: "xyz", views: 10 }
]
)
検索するTEXTフィールドにインデックスを作成する必要があります。インデックスを作成しないと、クエリが非常に遅くなります
db.articles.createIndex( { subject: "text" } )
db.articles.find( { $text: { $search: "coffee",$caseSensitive :true } } ) //FOR SENSITIVITY
db.articles.find( { $text: { $search: "coffee",$caseSensitive :false } } ) //FOR INSENSITIVITY
Regex ベースのクエリを使用する際に留意すべき非常に重要な点の 1 つは、ログイン システムでこれを行う場合、検索するすべての文字をエスケープし、^ および $ 演算子を忘れないことです。Lodash には、すでに使用している場合に備えて、このための優れた機能があります。
db.stuff.find({$regex: new RegExp(_.escapeRegExp(bar), $options: 'i'})
なんで?ユーザーが自分のユーザー名として入力することを想像してください.*
。これはすべてのユーザー名に一致し、任意のユーザーのパスワードを推測するだけでログインできます。
Mongo (現在のバージョン 2.0.0) では、インデックス付きフィールドに対して大文字と小文字を区別しない検索が許可されていません。ドキュメントを参照してください。インデックスのないフィールドの場合、他の回答にリストされている正規表現で問題ありません。
「テーブル」の「列」を検索し、大文字と小文字を区別しない検索を行うとします。最善かつ効率的な方法は次のとおりです。
//create empty JSON Object
mycolumn = {};
//check if column has valid value
if(column) {
mycolumn.column = {$regex: new RegExp(column), $options: "i"};
}
Table.find(mycolumn);
検索値を正規表現として追加し、オプションとして「i」を使用して設定された機密性の低い基準で検索するだけです。
Mongooseを使用すると、これがうまくいきました:
var find = function(username, next){
User.find({'username': {$regex: new RegExp('^' + username, 'i')}}, function(err, res){
if(err) throw err;
next(null, res);
});
}
最良の方法は、選択した言語で行うことです。オブジェクトのモデル ラッパーを作成するときは、save() メソッドを検索対象の一連のフィールドで繰り返し処理し、インデックスも作成します。これらのフィールドのセットには、検索に使用される対応する小文字が必要です。
オブジェクトが再度保存されるたびに、小文字のプロパティがチェックされ、メイン プロパティへの変更が反映されて更新されます。これにより、効率的に検索できるようになりますが、毎回 lc フィールドを更新するために必要な余分な作業が隠されます。
小文字のフィールドは、key:value オブジェクト ストア、または接頭辞 lc_ が付いたフィールド名です。クエリを簡素化するために 2 番目のものを使用します (深いオブジェクトのクエリは、混乱を招く場合があります)。
注: 基になるメイン フィールドではなく、lc_ フィールドにインデックスを付けたいと考えています。
Use RegExp, In case if any other options do not work for you, RegExp is a good option. It makes the string case insensitive.
var username = new RegExp("^" + "John" + "$", "i");;
use username in queries, and then its done.
I hope it will work for you too. All the Best.
フィルターで使用する、大文字と小文字を区別しない正規表現用の単純な Func を作成しました。
private Func<string, BsonRegularExpression> CaseInsensitiveCompare = (field) =>
BsonRegularExpression.Create(new Regex(field, RegexOptions.IgnoreCase));
次に、次のようにフィールドをフィルタリングするだけです。
db.stuff.find({"foo": CaseInsensitiveCompare("bar")}).count();