【发布时间】:2018-01-16 15:14:18
【问题描述】:
我在带有 InnoDB 全文索引的 MySQL 5.6 中有下表。
CREATE TABLE `blacklist_entries` (
`blacklist_entry_id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL,
`insertat` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`blacklist_entry_id`),
FULLTEXT KEY `ftk_b_n` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=660004 DEFAULT CHARSET=utf8
这是我们正在处理的数据。 name 中的所有条目都是单个单词,有时带有-,但不会超过一个单词。
mysql> select * from blacklist_entries where name like '%battle%';
+--------------------+---------------------+---------------------+
| blacklist_entry_id | name | insertat |
+--------------------+---------------------+---------------------+
| 4159 | battleground | 2018-01-16 12:15:46 |
| 604218 | battle | 2018-01-16 12:18:59 |
| 604219 | battlefield | 2018-01-16 12:18:59 |
| 604220 | battlefields | 2018-01-16 12:18:59 |
| 604221 | battles | 2018-01-16 12:18:59 |
| 660003 | abcbattle | 2018-01-16 12:49:34 |
+--------------------+---------------------+---------------------+
我想创建一个全文搜索此列表,该列表能够按相关性排序,其中完全匹配的得分高于部分匹配。
当我运行这个查询时
select
*,match(name) against ('battle battle* *battle' IN BOOLEAN MODE) as score
from blacklist_entries where match(name)
against ('battle battle* *battle' IN BOOLEAN MODE);
我得到以下结果。
+--------+---------------------+---------------------+--------------------+
| id | name | insertat | score |
+--------+---------------------+---------------------+--------------------+
| 4159 | battleground | 2018-01-16 12:15:46 | 17.11724281311035 |
| 604218 | battle | 2018-01-16 12:18:59 | 17.11724281311035 |
| 604219 | battlefield | 2018-01-16 12:18:59 | 17.11724281311035 |
| 604220 | battlefields | 2018-01-16 12:18:59 | 17.11724281311035 |
| 604221 | battles | 2018-01-16 12:18:59 | 17.11724281311035 |
+--------+---------------------+---------------------+--------------------+
这有两个问题。
- 所有结果都有相同的分数,甚至完全匹配
-
从右不匹配,缺少这一行
| 660003 | abcbattle | 2018-01-16 12:49:34 | 17.11724281311035 |
我可以更改查询中的某些内容以说服 MySQL 对这些匹配项进行不同的评分吗?
如果这不可能,是否有可行的替代方案,例如在存储过程中实现我自己的评分,并再次迭代完整列表以至少确定完全匹配以将其排名更高?
如果这些都不起作用,我将不得不在我的应用程序层中完全构建评分。显然这会花费额外的资源,所以我想避免这种情况。
【问题讨论】:
标签: mysql full-text-search innodb