我的任务是创建一个站点范围的搜索功能。搜索需要查看文章、事件和页面内容
我之前在 MySQL 中使用过 MATCH()/AGAINST() 并且知道如何获取结果的相关性,但据我所知,相关性对于搜索是唯一的(内容、行数等)结果的相关性来自文章表不会匹配事件表中结果的相关性。
无论如何要统一相关性,以便所有三个表的结果具有可比较的相关性?
我的任务是创建一个站点范围的搜索功能。搜索需要查看文章、事件和页面内容
我之前在 MySQL 中使用过 MATCH()/AGAINST() 并且知道如何获取结果的相关性,但据我所知,相关性对于搜索是唯一的(内容、行数等)结果的相关性来自文章表不会匹配事件表中结果的相关性。
无论如何要统一相关性,以便所有三个表的结果具有可比较的相关性?
是的,您可以使用 Apache Lucene 和 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 必须从子查询中获取所有结果才能评估父查询。