在我的应用程序(PHP/MySQL/JS),我有一个搜索功能内置。其中一个搜索条件包含各种选项的复选框,因此,一些结果会比其他结果更相关,如果它们包含或多或少的每个选项。
。选项是A和B,如果我同时搜索选项A和B,结果1只包含选项A的相关度为50%,而结果2同时包含选项A和B的相关度为100%。
先前,我只是做简单的SQL查询基于表单输入,但这一个有点难,因为它不像"%query%"这样简单的数据,而是,一些结果对一些搜索查询更有价值,而有些则不是。
我完全不知道从哪里开始…有人有相关的(哈!)阅读材料给我指路吗?
编辑:经过仔细考虑,我认为涉及SQL脚本来获取原始数据,然后进行许多轮解析是我必须做的事情…
没有可缓存的吗?(
看一下lucence项目它有多种语言版本
是PHP端口http://framework.zend.com/manual/en/zend.search.lucene.html
它索引要搜索的项目并返回相关的加权搜索结果,例如最好从y中选择x,其中名称像'%pattern%'样式搜索
你需要的是一个强大的搜索引擎,比如solr。虽然你可以在mysql上实现它,但它已经与其他工具一起提供了。
这里有一个想法:进行比较并将结果相加。和越大,匹配的条件越多。
像这样一个(愚蠢的)表如何:
- <
- 名称/gh>
- dob_year
- dob_month
- dob_day
查找与3/15/1980最相似的三个日期组成部分的人:
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的项目,但具有两个选项的项目的排名似乎更高。
如果你在两个选项上进行搜索,这很有效。但让我们假设你对这三个选项都进行了搜索。所有的项目现在共享相同的强度,这就是为什么为选项分配"权重"很重要。
你可以让值成为你的优势,但如果你的查询并不总是为相同的选项分配相同的权重,那可能对你没有帮助。这可以通过以下查询在每个查询的基础上轻松实现:
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
试试这些查询,看看是不是你需要的。
我还想指出,这不是处理能力方面的最佳解决方案。我建议您添加索引,使选项字段为整数,尽可能缓存结果。