2017-02-12 13 views
0

私はあなたの名前でユーザーを返し、ユーザーが持つことができるように、最初、中、姓を連結するのではなく、MySQL全文検索を選択した、正しい順序を心配することなく、名前を入力する際の柔軟性が向上します。MySQLの全文検索サブクエリで検索結果が返されない

など。 'Carolina Del'、 'Delgado Caro'などは、first_name = "Carolina"、middle_name = ""、last_name = "Delgado"のuser_namesテーブルの対応する値と一致します。

user/user_names制約の後に全文検索を使用すると何らかの理由でゼロの結果が得られますが、LIKEを使用すると正しい結果が得られます。

以下は0結果

SELECT count(*) FROM `users` 
    WHERE (select count(*) from `user_names` 
     WHERE `user_names`.`user_id` = `users`.`id` 
     AND MATCH(first_name, middle_name, last_name) 
     AGAINST ('+carolina' IN BOOLEAN MODE) 
    ) >= 1; 

私たちは47件の結果

SELECT count(*) FROM `users` 
    WHERE (select count(*) FROM `user_names` 
     WHERE `user_names`.`user_id` = `users`.`id` 
     AND `first_name` LIKE "%carolina%") 
    >= 1; 

とフルテキストインデックスが正しく機能していることを示すを取得LIKEとともに使用すると、ここでのクエリは上で直接あるを与えます47の結果も得られるユーザー名テーブル

SELECT count(*) FROM `user_names` 
    WHERE MATCH(first_name, middle_name, last_name) 
    AGAINST ('+carolina' IN BOOLEAN MODE); 

私は価値があるこれをLaravelクエリビルダのスコープで使用しますが、生成するSQL(上記)が機能していないため、まず理由を理解する必要があります。

public function scopeForContactName($query, $name) 
{ 
return $query->whereHas('contact.name', function ($query) use ($name) { 
     $query->where(function ($q) use ($name) { 
      $q->whereRaw("MATCH(first_name, middle_name, last_name) AGAINST (? IN BOOLEAN MODE)", [$name]); 
     }); 
    }); 
} 

答えて

0

これは、インデックスストレージを昇順に設定することで解決しました。

ので、同様に、私は以前にインデックスを作成していた。

CREATE FULLTEXT INDEX full_text_index ON `user_names` (`first_name`, `middle_name`, `last_name`) 

次の調整SQLは、問題を修正:

CREATE FULLTEXT INDEX full_text_index ON `user_names` (`first_name` ASC, `middle_name` ASC, `last_name` ASC) 

これは述べてMySQLのドキュメントに反するようだ:

index_col_nameの指定は、ASCまたはDESCで終了できます。これらのキーワードは、将来の拡張で、昇順または降順のインデックス値の格納を指定するために使用できます。現在、それらは解析されますが無視されます。インデックス値は常に昇順に格納されます。 MySQL 5.7 Docs

しかし、とにかく、私のために働く!

+0

'FULLTEXT'は' ASC'や 'DESC'という概念を持っていないので、これは何か違いがあったことに驚いています。 –

0

最初のクエリは意味をなさない。サブクエリは、1行 - カウントを返します。外部クエリでは、が正確にの1行をカウントするはずです。

この製剤からは何が得られますか?

SELECT count(*) 
    FROM `users` AS u 
    JOIN `user_names` AS un ON un.`user_id` = u.`id` 
    WHERE MATCH(un.first_name, un.middle_name, un.last_name) 
      AGAINST ('+carolina' IN BOOLEAN MODE); 

それはusersテーブルではなく、別のテーブルに名前を入れて(私には)より多くの意味があります。

関連する問題