繁体   English   中英

PHP / MySQL:简单的搜索引擎

[英]PHP/MySQL: Simple search engine

我正在为一个小型网站组合一个简单的搜索引擎。 用户将可以通过email addressname搜索他们的朋友。 我希望使用FULLTEXT搜索,但是我使用的是InnoDB表,因此使我回到了LIKE %keyword%

我的问题是用户的名字和姓氏存储在两个单独的列中。 我该如何搜寻“ 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;");
    }

看看Sphinx,它直接从MySQL索引数据,并具有用于搜索的PHP API。

除此之外,您可以在搜索文本中拆分空格并尝试几个OR,但是就像您说的那样,InnoDB中不存在相关性。

MySQL并不是真正为搜索而设计的,因此,从长远来看,使用另一种产品将更加灵活和可扩展。

搜索显然是一个大话题,并且有很多不同的处理方式。

也就是说,对于最基本的解决方案,您应该能够在这两个字段的串联中进行搜索:

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

MySQL的CONCAT()函数接受的串数与参数的串数相同。 在上述情况下,我们只是在FirstNameLastName之间添加了一个空格。

您应该考虑使用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)

您可以在MySQL中使用CONCAT()函数

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

如果不是全文搜索,那么您可能必须考虑拆分搜索词并查询类似以下内容:

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

这并不理想,我不确定这是否是最佳解决方案,但它可能会为您返回最佳结果集。 特别是如果人们开始使用三重桶装名称(例如“约翰·泰勒·史密斯”),这种情况似乎越来越普遍

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM