繁体   English   中英

设计“基于相关性”的搜索?

[英]Designing “relevance-based” search?

在我的应用程序(PHP/MySQL/JS)中,我内置了一个搜索功能。其中一个搜索条件包含各种选项的复选框,因此,如果某些结果包含更多或更少的每个选项。

即选项是 A 和 B,如果我同时搜索选项 A 和 B,则仅包含选项 A 的结果 1 是 50% 相关的,而同时包含选项 A 和 B 的结果 2 是 100% 相关的。

之前,我只是根据表单输入进行简单的 SQL 查询,但这有点困难,因为它不像数据 LIKE "%query%" 那样简单,而是某些结果对某些搜索查询更有价值,有些不是。

我完全不知道从哪里开始……有人有相关的(哈?)阅读材料可以指导我吗?

编辑:仔细考虑之后,我在想一些涉及 SQL 脚本来获取原始数据,然后进行多轮解析是我必须做的事情......

但是,没有可缓存的东西吗? :(

看看 lucence 项目,它有多种语言版本

this is the php port http://framework.zend.com/manual/en/zend.search.lucene.html

它对要搜索的项目进行索引并返回相关的加权搜索结果,例如比 select x from y where name like '%pattern%' style search 更好

您需要的是一个强大的搜索引擎,例如 solr。 虽然您可以在 mysql 之上实现此功能,但它已经随其他工具开箱即用。

这是一个想法:进行比较并总结结果。 总和越高,匹配的条件越多。

像这样的(愚蠢的)表怎么样:

  • 姓名
  • dob_year
  • dob_month
  • dob_day

找出与 1980 年 3 月 15 日共享三个日期组成部分中最多的人:

SELECT (dob_year = 1980) + (dob_month = 3) + (dob_day = 15) as strength, name
from user
order by strength desc
limit 1

需要一个好的 WHERE 子句和索引来阻止您进行表扫描,但是......

您甚至可以为列添加权重,例如

SELECT ((dob_year = 1980)*2)

祝你好运。

鉴于您对我的评论的回答,这里有一个关于如何做到这一点的示例:

首先是表:

CREATE TABLE `items` (
 `id` int(11) NOT NULL,
 `name` varchar(80) NOT NULL
);
CREATE TABLE `criteria` (
 `cid` int(11) NOT NULL,
 `option` varchar(80) NOT NULL,
 `value` int(1) NOT NULL
);

然后是一些项目和标准的示例:

INSERT INTO items (id, name) VALUES
(1,'Name1'),
(2,'Name2'),
(3,'Name3');

INSERT INTO criteria VALUES
(1,'option1',1) ,(1,'option2',1) ,(1,'option3',0),
(2,'option1',0) ,(2,'option2',1) ,(2,'option3',1),
(3,'option1',1) ,(3,'option2',0) ,(3,'option3',1);

这将创建 3 个项目和 3 个选项,并为它们分配选项。

现在,您可以通过多种方式按一定的“强度”进行排序。 其中最简单的是:

SELECT i . * , c1.value + c3.value AS strength
FROM items i
JOIN criteria c1 ON c1.cid = i.id AND c1.option = 'option1'
JOIN criteria c3 ON c3.cid = i.id AND c3.option = 'option3'
ORDER BY strength DESC 

这将向您显示所有具有选项 1 或选项 3 的项目,但同时具有这两个选项的项目似乎排名“更高。

如果您正在搜索 2 个选项,这很有效。 但是让我们假设您搜索所有 3 个选项。 现在所有项目都具有相同的强度,这就是为什么为选项分配“权重”很重要。

您可以将值作为您的优势,但如果您的查询并不总是将相同的权重分配给所有地方的相同选项,那么这可能对您没有帮助。 这可以通过以下查询在每个查询的基础上轻松实现:

SELECT i.* , IF(c1.value, 2, 0) + IF(c3.value, 1, 0) AS strength
FROM items i
JOIN criteria c1 ON c1.cid = i.id AND c1.option = 'option1'
JOIN criteria c3 ON c3.cid = i.id AND c3.option = 'option3'
ORDER BY strength DESC

尝试查询,看看它是否是您需要的。

我还想指出,就处理能力而言,这不是最佳解决方案。 我建议您添加索引,将选项字段设为 integer,尽可能缓存结果。

如果您有任何问题或要添加的内容,请发表评论。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM