Mysql fext 搜索两个字段并按匹配数排序

Mysql fext search on two fields and order by number of matches

有一个tableusers。它包含很多字段,但我们只需要 first_name 和名字。在这两个字段上还进行了 运行 搜索。 搜索查询非常简单:

SELECT 
  * 
FROM 
  `users` 
WHERE 
  `first_name` LIKE '%part1%' OR `first_name` LIKE '%part2%' OR 
  `last_name` LIKE '%part1%' or `last_name` LIKE '%part2%'

速度不快,但足够了。问题是按匹配次数排序。

id | first_name | last_name
1  | Steven     | Smith
2  | John       | Travolta
3  | John       | Smith

搜索字符串是John Smith。这些记录都是suitable,只是顺序错了。如何按匹配次数排序结果?

UPD

ORDER BY
  (`first_name` LIKE '%part1%') + (`first_name` LIKE '%part2%') + 
  (`last_name` LIKE '%part1%') + (`last_name` LIKE '%part2%') DESC

这个解决方案看起来不错,但是像 John JohnSmith Smith 这样的记录可以在需要的字符串

之前

您可以使用 MySQL

的自然语言处理功能
SELECT * FROM users,
  MATCH (first_name, last_name)
    AGAINST ('John Smith' IN BOOLEAN MODE) as Score
 WHERE MATCH (first_name, last_name)
    AGAINST ('John Smith' IN BOOLEAN MODE) ;

注意: InnoDB 表需要 MATCH() 表达式的所有列上的 FULLTEXT 索引才能执行布尔查询。即使没有 FULLTEXT 索引,针对 MyISAM 搜索索引的布尔查询也可以工作,尽管以这种方式执行的搜索会非常慢。

further information

In implementing this feature, MySQL uses what is sometimes referred to as implied Boolean logic, in which

+ stands for AND

- stands for NOT

[no operator] implies OR

你的 4 个条件中的每一个 returns 1 或 0 表示真或假,所以添加它们并降序排序:

ORDER BY
  (`first_name` LIKE '%part1%') + (`first_name` LIKE '%part2%') + 
  (`last_name` LIKE '%part1%') + (`last_name` LIKE '%part2%') DESC
SELECT *,   (`first_name` LIKE '%John%') 
          + (`first_name` LIKE '%Smith%') 
          + (`last_name`  LIKE '%John%') 
          + (`last_name`  LIKE '%Smith%') criteria
FROM `users` 
HAVING criteria > 0
ORDER BY criteria DESC

fiddle

PS。你真的需要喜欢吗?可以部分输入名称(例如 'avol' 以查找 'Travolta')?也许平等就足够了?

PPS。您甚至可以通过将单独的表达式与相应的权重系数相乘来设置一些匹配权重(例如,名字匹配优先于姓氏匹配)。