2

许多文章将指向全文索引,以获得 mysql 搜索的简单解决方案。在正确的情况下可能会出现这种情况,但是当无法使用全文时(例如,跨表),我还没有看到接近全文的解决方案。我正在寻找的解决方案最好是可以匹配句子中任何内容的解决方案。

因此, searchJames Woods或 searchWoods James可能都返回文本所在的同一行James Woods。基本的搜索方法会使搜索词的“混合匹配”变得无用。

REGEXP可能的答案是用or替换全文LIKE。然后将搜索词中的“空白”替换为|or可能会变为,%因此和的任何组合都会返回结果。或者变成'%James%Woods%',这会降低生产力,但仍然会返回匹配的结果。James WoodsJames|WoodsJamesWoodsaren't necessarily exact

示例 SQL

SELECT * FROM people
  LEFT JOIN 
   (SELECT GROUP_CONCAT(other_data) AS people_data GROUP BY people_id) 
   AS t2 ON(t2.people_id = people.id)
WHERE CONCAT_WS(' ', people.firstname, people.lastname, people_data) LIKE {$query}

这真的是最好的方法吗?是否有任何技巧可以使这种方法(或另一种方法)更有效地工作?我真的在寻找一个 mysql 解决方案,所以如果你的答案是使用另一个数据库服务,那么,就这样吧,我会接受它作为答案,但真正的问题是 mysql 的最佳解决方案。谢谢。

4

2 回答 2

0

在 MySQL 中,您是否尝试过使用

MATCH() 和 AGAINST() 函数的组合

我猜他们会产生你正在寻找的结果。

例如

对于以下数据集::

mysql> select * from temp;
+----+---------------------------------------------+
| id | string                                      |
+----+---------------------------------------------+
|  1 | James Wood is the matyr.                    |
|  2 | Wood James is the saviour.                  |
|  3 | James thames are rhyming words.             |
|  4 | Wood is a natural product.                  |
|  5 | Don't you worry child - Swedish House Mafia |
+----+---------------------------------------------+
5 rows in set (0.00 sec)

如果您需要 james 或 wood 存在,此查询将返回以下结果

mysql>  select string from temp where match (string) against ('james wood' in bo
olean mode);
+---------------------------------+
| string                          |
+---------------------------------+
| James Wood is the matyr.        |
| Wood James is the saviour.      |
| James thames are rhyming words. |
| Wood is a natural product.      |
+---------------------------------+
4 rows in set (0.00 sec)

如果您要求 James 和 Wood 这两个词都应该出现,则此查询将起作用。注意单词前的“+”号。检查这个布尔模式

mysql> select string from temp where match (string) against ('+james +wood' in b
oolean mode);
+----------------------------+
| string                     |
+----------------------------+
| James Wood is the matyr.   |
| Wood James is the saviour. |
+----------------------------+
2 rows in set (0.00 sec)

查找具有任何后缀的单词,它的工作方式类似

mysql> select string from temp where match (string) against ('Jame*' in boolean
mode);
+---------------------------------+
| string                          |
+---------------------------------+
| James Wood is the matyr.        |
| Wood James is the saviour.      |
| James thames are rhyming words. |
+---------------------------------+
3 rows in set (0.02 sec)

但请注意,Mysql 的全文搜索尚不支持前缀搜索

mysql> select string from temp where match (string) against ('*ame*' in boolean
mode);
Empty set (0.00 sec)

我希望这有帮助。

顺便说一句,这个回复很晚,但我有足够的兴趣来回复。

要了解更多信息,请查看此链接http://dev.mysql.com/doc/refman/5.5/en//fulltext-search.html

于 2013-03-21T17:32:04.623 回答
0

我参加聚会有点晚了-为此道歉。

您提到您不能使用全文功能,因为您正在使用连接 - 好吧,虽然情况确实如此,但有一种流行的方法可以解决这个问题。

考虑以下将全文搜索与连接结合使用:

SELECT
    article.articleID,
    article.title,
    topic.title
FROM articles AS article
-----
    INNER JOIN (
        SELECT articleID
        FROM articles
        WHERE MATCH (title, keywords) AGAINST ("cat" IN BOOLEAN MODE)
        ORDER BY postDate DESC
        LIMIT 0, 30
    ) AS ftResults ON article.articleID = ftResults.articleID
-----
LEFT JOIN topics AS topic ON article.topicID = topic.topicID
GROUP BY article.id
ORDER BY article.postDate DESC

请注意,我如何topics通过在另一个查询中运行全文搜索并按 ID 加入/匹配结果来保持我的加入完好无损。

如果您不在共享主机上,还可以考虑将SphinxLucene Solr与 MySQL 一起使用,以实现更快速的全文搜索。我用过 Sphinx 并强烈推荐它。

于 2015-10-11T16:49:00.813 回答