Php 当全文不是可行的解决方案时进行动态mysql搜索

Php 当全文不是可行的解决方案时进行动态mysql搜索,php,mysql,search,full-text-search,Php,Mysql,Search,Full Text Search,许多文章将向您介绍mysql搜索的简单解决方案的全文索引。在适当的情况下可能会出现这种情况,但当不能使用全文时(例如,跨表),我还没有看到接近全文的解决方案。我正在寻找的解决方案最好是能够匹配句子中的任何内容 因此,搜索James Woods或搜索Woods James都可能返回文本James Woods所在的同一行。基本的搜索方法会使搜索词的“混合匹配”毫无用处 可能的答案是将全文替换为REGEXP或LIKE。然后用|或%替换搜索词中的“空白”,因此詹姆斯·伍兹可能会变成詹姆斯·伍兹,因此詹姆

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

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

可能的答案是将全文替换为
REGEXP
LIKE
。然后用
|
%
替换搜索词中的“空白”,因此
詹姆斯·伍兹
可能会变成
詹姆斯·伍兹
,因此
詹姆斯
伍兹
的任何组合都将返回结果。或者变成“%James%Woods%”,这将降低效率,但仍将返回不一定精确的匹配项

示例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解决方案,所以如果你的答案是使用另一个DB服务,那么就这样吧,我会接受这个答案,但真正的问题是mysql的最佳解决方案。谢谢。

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

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

我想它们会产生你正在寻找的结果

e、 g

对于以下数据集::

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 ('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)
我希望这有帮助

好心的是,这个回复已经很晚了,但我很有兴趣回复


要了解更多信息,请查看此链接

我参加聚会有点晚了-为此表示歉意

您提到,您不能使用全文功能,因为您使用的是联接——好吧,虽然这是一种情况,但有一种流行的方法可以解决这个问题

使用全文搜索和联接时,请考虑以下事项:

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
请注意,我是如何通过在另一个查询中运行全文搜索并按ID加入/匹配结果来保持我的
主题的
连接完整的


如果不是共享主机,也可以考虑使用MySQL或与MySQL一起进行超快速全文搜索。我已经使用了Sphinx,并极力推荐它。

我不认为
%James%Woods%
会返回带有
Woods的记录。James
显然MySQL v5.6支持InnoDB engine@DoSparKot的FullTextSearch:是的,你说得对,我错误地将regexp版本与类似版本进行了比较。感谢您的回复,虽然它非常深入,并且有很多关于全文的好信息,但我的问题需要一个类似于全文的非全文解决方案。全文的问题在于,您不能将其用于
联接的
表。
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