记一次 MySql 下的分词搜索需求

本文技术栈 Spring Boot Mysql

中文分词搜索可以用很多实现方式,其中 ES 应该是比较快捷能够实现,但考虑到数据同步,业务复杂度,查询条件等问题,决定还是用 mysql 去实现。

中文分词工具

我这里随便找了一个分词工具 ansj_seg

<dependency>
  <groupId>org.ansj</groupId>
  <artifactId>ansj_seg</artifactId>
  <version>5.1.1</version>
</dependency>

同时借助 Hutool 的能力,即可完成分词

// 根据用户引入的分词引擎jar,自动创建对应的分词引擎对象
Result result = TokenizerUtil.createEngine().parse(query.getKeyword());

Sql 如何实现分词查询

使用正则表达式

select * from project p
where
p.name REGEXP CONCAT_WS('|',<foreach collection="param2.keywords" item="item" separator=",">#{item}</foreach>)

传入的 keyword =上海迪士尼摩天轮
组合后的 sql 大概为

select * from project p where p.name REGEXP '上海|迪士尼|摩天轮';

Sql 如何实现相关性排序

ES 中有个重要的能力,那就是查找时会有个相关性指数,排序会根据次指数返回,但 Mysql 却没这个指数。此时就有可能出现有一条记录的 namekeyword 完全相等,但查询的时候却不在第一个结果中。我们该如何操作呢

如果你是 8.0.4 那么恭喜你,直接可以使用 REGEXP_COUNT

SELECT column_name
FROM table_name
WHERE column_name REGEXP 'your_regex_pattern'
ORDER BY REGEXP_COUNT(column_name, 'your_regex_pattern') DESC;

如果你是低版本,那么可以使用

SELECT column_name
FROM table_name
WHERE column_name REGEXP 'your_regex_pattern'
ORDER BY LENGTH(column_name) - LENGTH(REPLACE(column_name, 'your_regex_pattern', '')) DESC;
消息盒子

# 暂无消息 #

只显示最新10条未读和已读信息