10

現在、次のコードを使用して複数の列を検索する単一の検索フィールドがあります。

$searchArray = explode(" ", $searchVal);
$query="SELECT * FROM users WHERE ";
$i=0;
foreach ($searchArray as $word) {
    if ($i != 0) $query .= " OR ";
    $query .= " MATCH (`first_name`, `last_name`, `email`) AGAINST ('".$word."*'  IN BOOLEAN MODE)";
    $i++;
}

テーブルに次の2つの行があるとします。

id | last_name | first_name | email
1  | Smith     | John       | john_smith@js.com
2  | Smith     | Bob        | bob_smith@js.com

「JohnS」と入力すると、最初の結果だけが望ましい動作を示します。

「JohnSmith」と入力すると、最初の結果だけが望ましい動作を示します。

「SmithJ」と入力すると、Bobが一致していなくても、両方の結果が表示されます。

「SmithJohn」と入力すると、Bobが一致していなくても、両方の結果が表示されます。

最後に、「Jo S」と入力すると、「Jo」と「S」が部分的に一致しても結果は返されません。

誰かが私のクエリを修正して、重要ではなく部分的な結果の一致である注文の目的の機能を処理するのを手伝ってもらえますか?最適な一致で並べ替えることができれば(つまり、単語の最も長い部分で、最初の文字から始まり、中央のセクションだけでなく、列の数が最も多い)、それも大きな助けになります。

アップデート:

ソリューションに基づいて機能する最終的なコードを投稿したかっただけです。ft_min_word_lenと同様に、複数の一致ステートメントを作成するループが正しくありませんでした。

私のコードは次のとおりです。

$searchArray = explode(" ", $searchVal);
$query="SELECT * FROM users WHERE  MATCH (`first_name`, `last_name`, `email`) AGAINST ('";
$i=0;
foreach ($searchArray as $word) {
    $query .= "+".$word."* ";
}
$query .= "' IN BOOLEAN MODE)";
4

3 に答える 3

11

ブールモードでは、(単に高いスコアを付けるのではなく)文字列が存在する必要があります。これは。で行われ+ます。プレフィックスの一致は、末尾が。で行われ*ます。これはあなたが望むもののようですので、以下を検索してください:

+John* +S*
+John* +Smith*
+Smith* +J*
+Jo* +S*

フルテキストインデックスは、「単語のどこでも」検索には役立たないことに注意してください。したがって、のようなもの*mith*は必ず失敗します。これらは、インデックスの文字1から一致することを意味します。

一致値で並べ替える場合、たとえば、John Smith before Johnny Smithsonが必要な場合は、次のようにします。

 SELECT * FROM user 
 WHERE MATCH(..fields..) AGAINST ('match' IN BOOLEAN MODE)
 ORDER BY MATCH(..fields..) AGAINST ('match' IN BOOLEAN MODE) DESC;

ft_min_word_len> =のすべての単語を個別に追加しない限り、どちらが表示されるかはわかりません。

+John* +S* John
+John* +Smith* John Smith
+Smith* +J* Smith
+Jo* +S*

最後の1つは、両方ともデフォルトの4文字未満であるため、デフォルトのmysqlにそのソートパラメータを追加することはできませんが、ft_min_world_len別の方法で設定することをお勧めします。

于 2013-03-12T21:05:10.097 に答える
2

IN BOOLEAN MODE-modifierを使用し+て強制するANDか、--modifierを使用して強制することができますNOT。演算子はありません、あなたの場合、オプションを意味します。

また、mysql構成で最小ワード長をチェックして、FULLTEXTINDEXインデックスワードを特定の長さより小さくする必要があります。

私は設定しなければなりませんでした

ft_min_word_len = 2

my.cnfで、これを有効にするためにインデックスを再構築する必要がありました。デフォルトでは3です。

min_word_lenを見つけるには、この質問を確認(および賛成)してください

于 2013-03-12T21:04:24.020 に答える
2

http://dev.mysql.com/doc/refman/5.5/en//fulltext-boolean.htmlを参照してください

単語の前に「+」、「-」、またはno演算子を配置して、「AND contains this word」、「NOT contains this word」、およびno演算子が「ORcontainsthisword」になるようにすることができます。

「JohnS」と入力すると、最初の結果だけが望ましい動作を示します。

Johnは1つしかないため、これは機能します。Sは最小単語長を下回り、破棄されます。

「JohnSmith」と入力すると、最初の結果だけが望ましい動作を示します。

ジョンは1人しかいないので、これは機能します

「SmithJ」と入力すると、Bobが一致していなくても、両方の結果が表示されます。

Jは最小単語長を下回っているため、両方の行で一致する唯一のスミス

「SmithJohn」と入力すると、Bobが一致していなくても、両方の結果が表示されます。

あなたはブールモードにいるので、MySQLはこれをスミスまたはジョンとして解釈します...スミスは両方に一致します。

最後に、「Jo S」と入力すると、「Jo」と「S」が部分的に一致しても結果は返されません。

JoとSは最小単語長を下回っています-MySQLはこれを何も検索していないものとして扱っていると思います

検索パラメータの前に「+」を追加して、それらをAND検索に変換することをお勧めします...+Smith +John

于 2013-03-12T21:09:05.100 に答える