2012-03-19 20 views
2

小さなサイト用の簡単な検索エンジンをまとめています。ユーザーはemail addressまたはnameで友だちを検索できます。私はFULLTEXT検索を使いたいと思っていましたが、InnoDBテーブルを使用していますので、LIKE %keyword%に戻ります。PHP/MySQL:簡易検索エンジン

私の問題は、ユーザーの姓と名が2つの別々の列に格納されていることです。 "David Rule"の検索はどうすればいいのでしょうか?それは一種の作品

if(filter_var($query,FILTER_VALIDATE_EMAIL)) { 
     $STH = $this->_db->prepare("SELECT UserID 
      FROM UserCredTable 
      WHERE EmailAddress = :query;"); 
    } else { 
     $STH = $this->_db->prepare("SELECT UserID 
      FROM UserInfoTable 
      WHERE FirstName LIKE :query 
      OR LastName LIKE :query;"); 
    } 

が、私は関連性を推測している、存在しないほとんどです:(

どのように並べ替え、最も関連性の高いことにより、次のことができます。ここでは

は私が現時点で持っているものです結果


更新:?

これはまともな解決策のようですか?

if(filter_var($query,FILTER_VALIDATE_EMAIL)) { 
     $params["query"] = $query; 
     $STH = $this->_db->prepare("SELECT UserID 
      FROM UserCredentials 
      WHERE EmailAddress = :query;"); 
    } else { 
     $params["query"] = "%".$query."%"; 
     $STH = $this->_db->prepare("SELECT UserID 
      FROM UserDetails 
      WHERE CONCAT(FirstName,' ',LastName) 
      LIKE :query;"); 
    } 
+0

パフォーマンスの観点からはありません。このクエリはインデックスを使用することができないため、大きなテーブルや使用量が多いと、サーバが遅くなります。小さなテーブルの場合は大丈夫です。 –

+0

@YourCommonSenseこれまでに検索された行は6千を超えません。そして、ごくまれにしかありません。それは受け入れられますか? –

+0

「非常にまれに」というのは、1日に最大50回という意味です。 –

答えて

0

検索は明らかに大きいですトピックを扱う方法がたくさんあります。

SELECT UserID 
     FROM UserInfoTable 
     WHERE CONCAT(FirstName, ' ', LastName) LIKE '%Dave Smith%'; 

あなたが引数として連結しているようCONCAT()のMySQL関数は、できるだけ多くの文字列を取ります。最も基本的な可能性のある解決策のために、あなたはこれら二つのフィールドの連結を検索することができるはず、と述べ

。上記の場合、ファーストネームファーストネームの間にスペースが追加されました。

-1

フルテキスト検索のサポートをMySQLや他の多くのデータベースエンジンに組み込むことを検討する必要があります。

あなたの検索にランキングを追加します。かなり素晴らしいです。

次の例では、MySQLのマニュアルからである

は、http://dev.mysql.com/doc/refman/5.0/en/fulltext-natural-language.html

mysql> CREATE TABLE articles (
    -> id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, 
    -> title VARCHAR(200), 
    -> body TEXT, 
    -> FULLTEXT (title,body) 
    ->) ENGINE=MyISAM; 
Query OK, 0 rows affected (0.00 sec) 

mysql> INSERT INTO articles (title,body) VALUES 
    -> ('MySQL Tutorial','DBMS stands for DataBase ...'), 
    -> ('How To Use MySQL Well','After you went through a ...'), 
    -> ('Optimizing MySQL','In this tutorial we will show ...'), 
    -> ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), 
    -> ('MySQL vs. YourSQL','In the following database comparison ...'), 
    -> ('MySQL Security','When configured properly, MySQL ...'); 
Query OK, 6 rows affected (0.00 sec) 
Records: 6 Duplicates: 0 Warnings: 0 

mysql> SELECT * FROM articles 
    -> WHERE MATCH (title,body) AGAINST ('database'); 
+----+-------------------+------------------------------------------+ 
| id | title    | body          | 
+----+-------------------+------------------------------------------+ 
| 5 | MySQL vs. YourSQL | In the following database comparison ... | 
| 1 | MySQL Tutorial | DBMS stands for DataBase ...    | 
+----+-------------------+------------------------------------------+ 
2 rows in set (0.00 sec) 
+1

*「FULLTEXT検索を使用したいが、InnoDBテーブルを使用したい」* – Ryan

+1

これはInnoDB – fire

+0

+1を使用して正しい解決方法には使えない –

3

Sphinxを見てください。それはMySQLから直接データをインデックスし、検索のためのPHP APIを持っています。

それ以外の場合は、検索テキストのスペースを分割していくつかのORを試すことができますが、関連性はInnoDBには存在しないと言いました。

MySQLは実際に検索用に設計されていないので、長期的にはより柔軟でスケーラブルな別の製品を使用しています。

-1

全文検索オプション、あなたはおそらく検索用語をsplitingし、このような何かをクエリを見ていると思いますされていない場合は、MySQL

} else { 
    $STH = $this->_db->prepare("SELECT UserID 
     FROM UserInfoTable 
     WHERE CONCAT(FirstName,LastName) LIKE '%:query%';"); 
} 
-1

でCONCAT()関数を使用することができます。

SELECT UserID 
FROM UserInfoTable 
WHERE (FirstName LIKE '%David%' 
OR LastName LIKE '%David%') OR 
(FirstName LIKE '%:Rule%' 
OR LastName LIKE '%:Rule%') 

これは最適なソリューションであるかどうかは不明ですが、おそらく最適な結果セットが返されます。特に、一般的になっていると思われるトリプルバレルの名前(例えば、「John Taylor Smith」)が始まる場合は、