フィールドに文字列が含まれているかどうかの確認


454

フィールドの値に特定の文字列が含まれているかどうかを確認できる演算子を探しています。

何かのようなもの:

db.users.findOne({$contains:{"username":"son"}})

それは可能ですか?

回答:


693

次のコードでそれを行うことができます。

db.users.findOne({"username" : {$regex : ".*son.*"}});

16
これはインデックスを効率的に使用せず、すべての値が一致するかどうかスキャンされることに注意してください。正規表現
Stennie

7
@Stennie、次に、インデックスを効率的に使用して部分文字列を見つけるために何を提案しますか?
Blue Sky

4
@Vish:一般的な使用例がフィールドのフリーテキスト検索であり、大量のドキュメントがある場合、より効率的なクエリのためにテキストをトークン化します。単純な全文検索にマルチキーを使用したり、逆のインデックスを別のコレクションとして作成したりできます。検索の頻度が低い場合や、ドキュメントのコレクションが少ない場合は、インデックス全体をスキャンすることで許容できるパフォーマンスが得られます(最適ではありません)。
ステニー

98
これはちょっとやりすぎではありませんか?あなたが欲しいのは db.users.findOne({"username" : {$regex : "son"}});
JamieJag 2014年

3
Mongo 2.6の全文検索をチェックしたいかもしれません
wprl

179

Mongoシェルは正規表現をサポートしているため、それは完全に可能です。

db.users.findOne({"username" : /.*son.*/});

クエリで大文字と小文字を区別しないようにする場合は、次のように「i」オプションを使用できます。

db.users.findOne({"username" : /.*son.*/i});

参照:http : //www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-RegularExpressions


1
検索に正規表現を使用する方法を示すコードスニペットを含めてください。回答には、単なるリンクよりも多くの情報を含める必要があります...
maerics

1
選択された回答は私にとってはうまくいきませんでしたが、これは機能しました(私はdocker execコマンドを介してmongoクエリを実行しています)。
Arthur Weborg

5
選択した回答のコメントのように、私はdb.users.findOne({"username" : /.*son.*/});やり過ぎかもしれませんし、正規表現も簡単かもしれません/son/
Arthur Weborg

2
$ regexを使用するよりも簡潔な方法
Lionet Chen 2018

4
これを編集して使用{ username: /son/ }
Wyck

150

https://docs.mongodb.com/manual/reference/sql-comparison/

http://php.net/manual/en/mongo.sqltomongo.php

MySQL

SELECT * FROM users WHERE username LIKE "%Son%"

MongoDB

db.users.find({username:/Son/})

8
MongoDBの回答は適切です。質問を編集して、無関係なMySQLアドバイスを削除することを検討してください。
maerics 2012年

31
クエリをすべて削除するか、変更しますか?ほとんどの人々はSQLを知っています。MongoDBを理解するのに役立ちます
Zheng Kai

4
@ZhengKai:このWebサイトでは、通常、タグ付けおよび要求された特定のテクノロジのみを使用して、質問に直接回答する必要があります。
maerics 2012年

98
@maerics個人的には、ZhengがMySQLを含めることは、それが基準を提供するので非常に有用であることがわかりました。
Mike Bartlett

50
また、SQL参照も関連していると思いました。
vikingsteve 2013

69

バージョン2.4以降では、フィールドにテキストインデックスを作成して検索し、クエリに$ text演算子を使用できます

まず、インデックスを作成します。

db.users.createIndex( { "username": "text" } )

次に、検索するには:

db.users.find( { $text: { $search: "son" } } )

ベンチマーク(〜15万文書):

  • 正規表現(その他の回答)=> 5.6〜6.9秒
  • テキスト検索=> .164〜.201秒

ノート:

  • コレクションに含めることができるテキストインデックスは1つだけです。次のような文字列フィールドを検索する場合は、ワイルドカードテキストインデックスを使用できますdb.collection.createIndex( { "$**": "text" } )
  • テキストインデックスは大きくなる可能性があります。これには、挿入された各ドキュメントの各インデックス付きフィールド内の一意のポストステム単語ごとに1つのインデックスエントリが含まれます。
  • テキストインデックスは、通常のインデックスよりも作成に時間がかかります。
  • テキストインデックスは、フレーズやドキュメント内の単語の近接性に関する情報を格納しません。その結果、コレクション全体がRAMに収まると、フレーズクエリがより効率的に実行されます。

14
いいえ、完全なテキスト演算子は「次を含む」の実行を許可しないため、完全に一致する単語のみを返します。現在3.0の時点での唯一のオプションは、regexを使用することです。つまり、db.users.find({username:/ son / i} )これは、「息子」を含むすべてのユーザーを検索します(大文字小文字を区別)
comeGetSome

3
コレクションにドキュメントを追加またはコレクションからドキュメントを削除するときに、インデックスを再作成する必要がありますか?
Jake Wilson、

質問のタイトルには「含む」と書かれています。全文検索は質問には適用されません。
Donato

29

これは検索エンジンの最初のヒットの1つであり、上記のいずれもMongoDB 3.xでは機能しないように思われるため、機能する正規表現検索を1つ示します。

db.users.find( { 'name' : { '$regex' : yourvalue, '$options' : 'i' } } )

追加のインデックスなどを作成する必要はありません。


1
正規表現は消毒する必要があります。
ショーン

16

Pythonを介してMongoDBに接続する場合は、次のことを行う必要があります

db.users.find({"username": {'$regex' : '.*' + 'Son' + '.*'}})

'Son'の代わりに変数名を使用して、文字列を連結することもできます。


es2015では、バックティック{$ regex:.*${value}.*}を使用できます
Michael Guild

16

このタスクを実行する最も簡単な方法

クエリで大文字と小文字を区別する場合

db.getCollection("users").find({'username':/Son/})

クエリで大文字と小文字を区別しない場合

db.getCollection("users").find({'username':/Son/i})

1
正規表現で変数を使用する方法?
Hisham

4

大文字と小文字を区別しないためのインデックスiオプションの使用に理想的な答え

db.users.findOne({"username" : new RegExp(search_value, 'i') });

正規表現は消毒する必要があります。
ショーン


1

RegExp一致でHTMLタグを無視する方法:

var text = '<p>The <b>tiger</b> (<i>Panthera tigris</i>) is the largest <a href="https://stackoverflow.com/wiki/Felidae" title="Felidae">cat</a> <a href="https://stackoverflow.com/wiki/Species" title="Species">species</a>, most recognizable for its pattern of dark vertical stripes on reddish-orange fur with a lighter underside. The species is classified in the genus <i><a href="https://stackoverflow.com/wiki/Panthera" title="Panthera">Panthera</a></i> with the <a href="https://stackoverflow.com/wiki/Lion" title="Lion">lion</a>, <a href="https://stackoverflow.com/wiki/Leopard" title="Leopard">leopard</a>, <a href="https://stackoverflow.com/wiki/Jaguar" title="Jaguar">jaguar</a>, and <a href="https://stackoverflow.com/wiki/Snow_leopard" title="Snow leopard">snow leopard</a>. It is an <a href="https://stackoverflow.com/wiki/Apex_predator" title="Apex predator">apex predator</a>, primarily preying on <a href="https://stackoverflow.com/wiki/Ungulate" title="Ungulate">ungulates</a> such as <a href="https://stackoverflow.com/wiki/Deer" title="Deer">deer</a> and <a href="https://stackoverflow.com/wiki/Bovid" class="mw-redirect" title="Bovid">bovids</a>.</p>';
var searchString = 'largest cat species';

var rx = '';
searchString.split(' ').forEach(e => {
  rx += '('+e+')((?:\\s*(?:<\/?\\w[^<>]*>)?\\s*)*)';
});

rx = new RegExp(rx, 'igm');

console.log(text.match(rx));

これは、おそらく非常に簡単にMongoDB集約フィルターに変えることができます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.