2016-03-27 3 views
0

私はキーワードのリストを持っている:フィールドにすべてのキーワードが存在するmongodb(pymongo)のドキュメントを照会するには?

今の
keywords = ['word1', 'word2', 'word3'] 

私はこのような1つだけのキーワードを照会:私はレゲエを行うので、私は決して正規表現での第一人者だ

collection.find({'documenttextfield': {'$regex': ' '+keyword+' '}}) 

正確な一致を見つけるためにキーワードの横のスペース。

しかし、今私が望むのは、のリストから各キーワードを持つものを検索して検索することです。keywordsリストです。

私はこれを行う方法のいくつかのアイデアを持っていますが、それらはすべて少し複雑すぎると私は...

+0

キーワードの表示順序がわからない場合は、1つの正規表現は役に立ちません。 [テキストインデックス](https://docs.mongodb.org/manual/core/index-text/)の使用を検討しましたか? – Philipp

答えて

1

$text searchtext indexの使用を検討して何かが欠けてる感じ。正規表現を使うよりはるかに良い解決策かもしれません。ただし、テキスト検索ではスコアリングアルゴリズムに基づいてドキュメントが返されますので、探しているキーワードがすべて含まれていない結果が生じることがあります。

このフィールドにテキストインデックスを追加できない場合、または1つの正規表現を使用すると、これらの単語の表示順​​序がわからないため、非常に苦労します。私は書くことは不可能ではないと主張していませんが、あなたは正規表現の基準でさえ恐ろしい憎悪で終わるでしょう。 $and演算子を使用すると、regex演算子を複数回使用する方がはるかに簡単です。

また、区切り文字としてスペースを使用すると、単語が文字列の先頭または末尾にあるか、ピリオドまたはコンマが続くときに失敗します。代わりに単語境界トークン(\b)を使用してください。

collection.find(
    { $and : [ 
       {'documenttextfield': {'$regex': '\b' +keyword1+'\b'}}, 
       {'documenttextfield': {'$regex': '\b' +keyword2+'\b'}}, 
       {'documenttextfield': {'$regex': '\b' +keyword3+'\b'}}, 
     ] 
    }); 

これは、これらの3つの正規表現がコレクションのすべてのドキュメントで実行されるため、これは実際には遅いクエリであることに注意してください。これがパフォーマンス重視のクエリである場合、テキストインデックスが実際には機能しないかどうかを真剣に検討してください。これに失敗すると、最終的な把握は、documenttextfieldフィールドから検索できるフィールド(すべてのユニークワード)を新しいアレイフィールドdocumenttextfield_keywordsに抽出し、そのフィールドに通常のインデックスを作成して検索しますそのフィールドには$all operator(その場合は正規表現は不要です)。

+0

ありがとう!私は、テキストフィールドごとにキーワードを組み立てて、同じ文書に格納するというショットを出します!それは実際にはとても素敵な良い方法です。私はそれを行う手段があると私は確かに3正規表現よりもうまくいくはずだと思う! – GeekSince1982

+1

@ GeekSince1982 '$ all'を使うのはずっとあまりあいません' {"documenttextfield":{"$ all":re.compile( '\ b' +キーワード '\ b'、re.IGNORECASE) } '。しかし、 ''と ''や ''や ''のような "ストップワード"が必要な場合を除き、 '$ text'がおそらくもっと効率的です。その効率を達成するためにはかなり大きな索引が必要であり、通常、文書の「より大きい」テキストフィールドは小さなものよりも適していることに注意してください。 –

+0

@ GeekSince1982ここでの「その他」の省略は、「テキスト検索」が**用語のリストと一致する文書のみを返すことではないということです。 ** all **の一致する文書は「トップランク」の結果になりますが、テキスト検索条件は「OR」条件であるため、含まれる他の用語が返されます。排他的に "AND"を書く方法はありません。また上記の私の主なポイントは、答えが間違って '$ all' **が**配列が機能するのを必要としているということです。実際にはそうではなく、実際には、プロパティと一致する必要のある「引数のリスト」であり、それ以外の方法ではありません。人々はこれを間違っている。 –

関連する問題