操作方法:排名搜索结果

时间:2008-09-06 19:29:57

标签: php mysql search

我有一个webapp开发问题,我已经开发了一个解决方案,但我正在尝试寻找可能解决我遇到的一些性能问题的其他想法。

问题陈述:

  • 用户输入多个关键字/代币
  • 应用程序搜索与令牌匹配的内容
  • 每个令牌都需要一个结果
    • 即,如果一个条目有3个令牌,我需要输入id 3次
  • 对结果进行排名
    • 为令牌匹配分配X点
    • 根据点数对条目ID进行排序
    • 如果点值相同,请使用日期对结果进行排序

我希望能够做但却没有想到的是,发送1个返回类似于in()的结果的查询,但为每个条目的每个令牌匹配返回一个重复的条目ID检查。

有没有比我正在做的更好的方法,使用每个令牌运行一个查询的多个单独查询?如果是这样,那么最简单的方法是什么呢?

修改
我已经对条目进行了标记,因此,例如,“see spot run”的条目ID为1,有三个标记,“see”,“spot”,“run”,这些标记位于单独的标记表中,条目ID与它们相关,因此表格可能如下所示:

'see', 1 
'spot', 1 
'run', 1 
'run', 2 
'spot', 3 

4 个答案:

答案 0 :(得分:6)

你可以在一个查询中使用MySQL中的“UNION ALL”来实现这一点。

只需循环遍历PHP中的标记,为每个标记创建一个UNION ALL:

例如,如果令牌为'x','y'和'z',则您的查询可能看起来像这样

SELECT * FROM `entries` 
WHERE token like "%x%" union all 
    SELECT * FROM `entries` 
    WHERE token like "%y%" union all 
        SELECT * FROM `entries` 
        WHERE token like "%z%" ORDER BY score ect...

order子句应该作为一个整个结果集运行,这就是你需要的。

就性能而言,它不会那么快(我猜),但是对于数据库而言,速度方面的主要开销通常是从PHP向数据库引擎发送查询并接收结果。使用这种技术,这只发生一次而不是每个令牌一次,因此性能会提高,我只是不知道它是否足够。

答案 1 :(得分:3)

我知道这不是一个问题的答案,但如果你的表是数千行而不是数百万行,那么FULLTEXT解决方案可能是最好的方法

在MySQL中,当您在索引列上使用MATCH时,您提供的每个关键字都将获得一个相关性分数(大致按每个关键字的提及次数计算),这将比您的方法更准确,当然更有效多个关键字。

见这里: http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html

答案 2 :(得分:1)

如果您使用的是UNION ALL模式,您可能还希望在查询中包含以下部分:

SELECT COUNT(*) AS C
...
GROUP BY ID
ORDER BY c DESC

虽然这是一个非常简单的例子,它确实可以获得每个结果的匹配频率,这可能是一个伪等级开始。

答案 3 :(得分:0)

如果使用专为搜索任务而非数据库设计的数据结构,则可能会获得更好的性能。例如,您可以尝试构建inverted index。但是,您可能还需要查看Lucene之类的内容,而不是自己编写代码。

可以为您完成大部分工作。