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 John
和 Smith 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 搜索索引的布尔查询也可以工作,尽管以这种方式执行的搜索会非常慢。
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
PS。你真的需要喜欢吗?可以部分输入名称(例如 'avol' 以查找 'Travolta')?也许平等就足够了?
PPS。您甚至可以通过将单独的表达式与相应的权重系数相乘来设置一些匹配权重(例如,名字匹配优先于姓氏匹配)。
有一个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 John
和 Smith 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 搜索索引的布尔查询也可以工作,尽管以这种方式执行的搜索会非常慢。
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
PS。你真的需要喜欢吗?可以部分输入名称(例如 'avol' 以查找 'Travolta')?也许平等就足够了?
PPS。您甚至可以通过将单独的表达式与相应的权重系数相乘来设置一些匹配权重(例如,名字匹配优先于姓氏匹配)。