在mysql中对多个字段进行加权搜索的最佳方法?

时间:2011-06-27 17:52:58

标签: php mysql search

这就是我想要做的事情:

  • 将搜索主题与我的表格的多个字段匹配
  • 按字段的重要性和匹配的相关性(按此顺序)
  • 排序结果

Ex:我们假设我有一个博客。然后有人搜索“php”。结果将是这样的:

  • 首先,字段'title'的匹配,按相关性排序
  • 然后,字段'body'的匹配,按相关性排序
  • 以及指定的字段......

我实际上用PHP中的一个类做了这个,但它使用了很多UNIONS(很多!)并且随着搜索主题的大小而增长。所以我担心性能和DOS问题。有没有人对此有所了解?

6 个答案:

答案 0 :(得分:35)

这种加权搜索/结果的方法可能适合您:

SELECT *,
    IF(
            `name` LIKE "searchterm%",  20, 
         IF(`name` LIKE "%searchterm%", 10, 0)
      )
      + IF(`description` LIKE "%searchterm%", 5,  0)
      + IF(`url`         LIKE "%searchterm%", 1,  0)
    AS `weight`
FROM `myTable`
WHERE (
    `name` LIKE "%searchterm%" 
    OR `description` LIKE "%searchterm%"
    OR `url`         LIKE "%searchterm%"
)
ORDER BY `weight` DESC
LIMIT 20

它使用select子查询来提供排序结果的权重。在这种情况下,搜索了三个字段,您可以指定每个字段的权重。它可能比工会便宜,而且可能只是普通MySQL中更快的方法之一。

如果你有更多的数据并且需要更快的结果,你可以考虑使用像Sphinx或Lucene这样的东西。

答案 1 :(得分:9)

你可以将多个mysql MATCH()值一起添加,首先将每个值乘以它们的权重。

当然简化了......

'(MATCH(column1) AGAINST(\''.$_GET['search_string'].'\') * '.$column1_weight.')
 + (MATCH(column2) AGAINST(\''.$_GET['search_string'].'\') * '.$column2_weight.')
 + (MATCH(column3) AGAINST(\''.$_GET['search_string'].'\') * '.$column3_weight.')
 AS relevance'

然后

'ORDER BY relevance'

答案 2 :(得分:1)

您应该使用专用的索引器将所有数据预取到优化的可搜索索引中。 Sphinx和类似的产品做得非常好。

答案 3 :(得分:1)

我有一个完全相同的问题,它在一个MySQL论坛上得到了充分的回答。 Here's the thread.有点长篇大论(因为我有点啰嗦),但收益正是你所期待的。

答案 4 :(得分:1)

有一种使用MySQL的CASE函数(https://dev.mysql.com/doc/refman/5.7/en/case.html)的原生方法。

示例(未经测试):

SELECT * FROM `myTable` 
WHERE (`name` LIKE "%searchterm%" OR `description` LIKE %searchterm%" OR `url` LIKE "%searchterm%")
ORDER BY CASE
WHEN `name`        LIKE "searchterm%"  THEN 20
WHEN `name`        LIKE "%searchterm%" THEN 10
WHEN `description` LIKE "%searchterm%" THEN 5
WHEN `url`         LIKE "%searchterm%" THEN 1
ELSE 0
END
LIMIT 20

已将其用于我自己的许多加权搜索,并且绝对有效!

答案 5 :(得分:1)

SELECT post_name, post_title,
    (CASE WHEN `post_name` LIKE '%install%' THEN(9 / LENGTH(post_name) * 100) ELSE 0 END) 
    + (CASE WHEN `post_title` LIKE '%install%' THEN(9 / LENGTH(post_title) * 50) ELSE 0 END)
        AS priority
FROM wp_posts
WHERE
    post_title LIKE '%install%'
    OR post_name LIKE '%install%'
ORDER BY priority DESC

此查询不仅会检查列中的权重,还会检查每一行中的权重:

  • 检查搜索字在每个字段单元中的重要性。例如,如果搜索install(重量计算中包括长度),install something就会胜过install
  • 每个字段都可以分配权重(在这种情况下为100和50,可选)。

基本上,如果我们具有这些值并搜索install :( 1列示例,但它也适用于多列)

  • “关于安装的其他信息”
  • “安装”
  • “安装一些东西”

搜索将给出以下顺序:

  • 安装”-128重量
  • 安装某些东西”-52重量
  • “关于安装的其他内容”-32磅