Mysql全文搜索跨多个表的相关性



我的任务是创建一个站点范围的搜索功能。搜索需要查看文章、事件和页面内容

我以前在MySQL中使用过MATCH()/AGAINST(),知道如何获得结果的相关性,但据我所知,相关性对于搜索是唯一的(内容、行数等),articles表中结果的相关性与events表中的结果的相关性不匹配。

是否有办法统一相关性,使所有三个表的结果具有可比较的相关性?

是的,使用ApacheLucene和Solr等搜索引擎可以很好地统一它们。

http://lucene.apache.org/solr/

如果只需要在MySQL中进行,可以使用UNION来完成。您可能想要抑制任何零相关的结果。

您需要根据匹配的表来决定如何影响相关性。

例如,假设您希望文章是最重要的,事件是中等重要的,页面是最不重要的。你可以使用这样的乘数:

set @articles_multiplier=3;
set @events_multiplier=2;
set @pages_multiplier=1;

下面是一个你可以尝试的工作示例,它演示了其中的一些技术:

创建样本数据:

create database d;
use d;
create table articles (id int primary key, content text) ENGINE = MYISAM;
create table events (id int primary key, content text) ENGINE = MYISAM;
create table pages (id int primary key, content text) ENGINE = MYISAM;
insert into articles values 
(1, "Lorem ipsum dolor sit amet"),
(2, "consectetur adipisicing elit"),
(3, "sed do eiusmod tempor incididunt");
insert into events values 
(1, "Ut enim ad minim veniam"),
(2, "quis nostrud exercitation ullamco"),
(3, "laboris nisi ut aliquip");
insert into pages values 
(1, "Duis aute irure dolor in reprehenderit"),
(2, "in voluptate velit esse cillum"),
(3, "dolore eu fugiat nulla pariatur.");

使其可搜索:

ALTER TABLE articles ADD FULLTEXT(content);
ALTER TABLE events ADD FULLTEXT(content);
ALTER TABLE pages ADD FULLTEXT(content);

使用UNION搜索所有这些表:

set @target='dolor';
SELECT * from (
  SELECT 
    'articles' as 'table_name', id, 
    @articles_multiplier * (MATCH(content) AGAINST (@target)) as relevance
    from articles
  UNION
  SELECT 
    'events' as 'table_name', 
    id,
    @events_multiplier * (MATCH(content) AGAINST (@target)) as relevance
    from events
  UNION
  SELECT 
    'pages' as 'table_name', 
    id, 
    @pages_multiplier * (MATCH(content) AGAINST (@target)) as relevance
    from pages
)
as sitewide WHERE relevance > 0;

结果:

+------------+----+------------------+
| table_name | id | relevance        |
+------------+----+------------------+
| articles   |  1 | 1.98799377679825 |
| pages      |  3 | 0.65545331108093 |
+------------+----+------------------+

(对不起,我想把这作为对以上答案的评论,但我没有足够的声誉来评论)

请注意,子查询中的UNION优化得非常差。一种常见的情况是,当您想在父查询中使用"LIMIT@page*10,10"对结果进行分页时,MySQL必须从子查询中获得所有结果,才能评估父查询。

相关内容

  • 没有找到相关文章

最新更新