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

2022-08-30 17:01:03

这是我想做的:

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

例如:假设我有一个博客。然后有人搜索“php”。结果将如下所示:

  • 首先,字段“title”的匹配项,按相关性排序
  • 然后,字段“body”的匹配项,也按相关性排序
  • 等等,使用指定的字段...

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


答案 1

也许这种进行加权搜索/结果的方法适合您:

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

它使用选择子查询来提供对结果进行排序的权重。在本例中,搜索了三个字段,您可以为每个字段指定权重。它可能比联合更便宜,并且可能是纯MySQL中更快的方法之一。

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


答案 2

您可以将多个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'

推荐