使用MySQL在多个表中进行全文搜索来汇总最相关的结果

时间:2012-04-19 07:05:09

标签: mysql algorithm full-text-search

我在MySQL 5.5.22上的多个表上运行全文查询。该应用程序使用innodb表,因此我创建了一些专门用于全文搜索的MyISAM表。

例如,我的一些表看起来像

account_search
===========
id
account_id
name
description
hobbies
interests

product_search
===========
id
product_id
name
type
description
reviews

由于这些表仅用于全文搜索,因此它们是非规范化的。数据可以来自多个表,并聚集到搜索表中。除了ID列之外,其余列都分配给1个全文索引。

要使用全文搜索解决“50%”规则,我使用IN BOOLEAN MODE

所以对于上面的内容,我会跑:

SELECT *, MATCH(name, type, description, reviews) AGAINST('john') as relevance
FROM product_search
WHERE MATCH(name, type, description, reviews) AGAINST('john*' IN BOOLEAN MODE) LIMIT 10

SELECT *, MATCH(name, description, hobbies, interests) AGAINST('john') as relevance
FROM account_search
WHERE MATCH(name, description, hobbies, interests) AGAINST('john*' IN BOOLEAN MODE) LIMIT 10

我们假设我们也有称为“john”的产品:P

我面临的问题是:

  • 要获得有意义的相关性,我需要使用不带IN BOOLEAN MODE的搜索。这意味着搜索受50%规则和字长规则的约束。因此,通常情况下,如果product_search表中的大部分产品都被称为john,则它们的相关性将返回为0.

  • 多个查询之间的相关性无法比较。 (我认为来自一个查询的14的相关性不等于14与另一个不同查询的相关性。)

  • 搜索不仅限于这两个表,还有其他“对象类型”,例如:“订单”,“交易”等。

我希望能够在给定一组关键字的情况下返回所有对象类型的前7个最相关的结果(1个搜索框返回所有对象的结果)。

鉴于上述情况,有哪些算法或甚至更好的想法可以获得前7名?

我知道我可以使用像solr和elasticsearch这样的东西,我已经尝试过它们并且正在将它们集成到应用程序中,但我希望能够为那些只能访问MySQL的人提供搜索。

1 个答案:

答案 0 :(得分:0)

所以在考虑了一段时间后,我决定相关性排名必须在MySQL中进行1次查询。

这是因为:

  • 无法比较单独查询之间的相关性。
  • 很难以有意义的方式将多个搜索的内容组合在一起。

我已经切换到使用专用于搜索的1个索引表。根据对innodb表中真实底层数据的插入,删除和更新,插入,删除和更新条目(这都是自动的)。

表格如下:

search
==============
id //id for the entry
type //the table the data came from
column //column the data came from
type_id //id of the row the in the original table
content //text

内容列上有一个全文索引。重要的是要意识到并非所有表中的所有列都被编入索引,只添加了我认为在搜索中有用的内容。

因此,只是运行查询以匹配content,检索我们拥有的内容并进行进一步处理的简单案例。要处理最终结果,需要更多的查询来向父表询问搜索结果的标题以及可能的其他元数据,但这是一个可行的解决方案。

我认为这种方法不会真正扩展(更新和插入也需要更新此表),但我认为这是为应用程序的较小部署提供体面的应用程序范围搜索的一种非常好的方法。 / p>

对于可伸缩性,请使用弹性搜索,solr或lucene之类的东西。