商城搜索框分词处理

从产品拿到了一个需求,要求搜 “jordan3男款” 要显示出 ”AJ 3 Retro Chlorophyll 叶绿素 男款136064-006“ 这款鞋子
商城现在的搜索使用的是like %%方法,只能简单的搜出连续出现 ”jordan3男款“ 标题的产品,于是我对这串文字做了分析

首先 ‘jordan3女款’ 含有三种类型的字符: 英文,数字, 中文,如果对其拆分,可以得到 ‘jordan|3|女款’, 这一下肯定不能使用like来做了,于是我选择使用regexp_like来处理,分词之间也不能使用或的关系了,为了达到目的我把 ”|“ 换成了.*

于是like %jordan3男款% 变成了

regexp_like(field, 'jordan.*3.*女款', 'i')

这样做 3和女款满足了,但是jordan => aj依然不行,于是我想到了使用字符串映射来达到目的,原理很简单写一个映射,jordan映射成aj即可,出于可配置,我在后台写了一个列表管理,效果如下

jordan
为了防止标题AJ3变成了 jordan3 这里查询aj或者查询 jordan都会对这两个做搜索,于是变成了

regexp_like(field, '(jordan|aj).*3.*女款', 'i')

很显然,满足产品需求了呀,果断撸了代码提交测试

很快便被打脸了,测试发现一款nike也被搜了出来,它的标题是这样的 “耐克/Nike Air More Uptempo 皮蓬 跑步鞋 红色 AJ3138-600 女款”, 我怀疑nike出这个系列是为了挖aj3关键词的吧 🤦🏻‍♀️

痛定思痛,于是我再一次对 “jordan3女款” 和 “AJ 3 Retro Chlorophyll 叶绿素 男款136064-006” 产品做对比,同时跟产品讨论了一番,他告诉我3是aj的一个系列,甚至1, 2系列也都有,系列前面很大可能会加空格。

于是我果断放弃了拆成三种类型,改成拆成两种类型英文和数字放在了一起, “jordan3女款” => “jordan3|女款”, 同时对映射也做了处理

jordan3
处理出来的like语句也变成了

regexp_like(field, '(jordan3|aj 3).*女款', 'i')

深吸一口气,终于完成了,美滋滋提交测试

qa经过一番严格的暴力测试,告诉我说 ”耐克女款“ 搜不到 ”耐克/Nike Air More Uptempo 皮蓬 跑步鞋 红色 AJ3138-600 女款"

我。。。。。。

考虑一番,我发现这需要中文分词,而不是简单的只做类型区分就行的。
于是我找到了ajsi, github地址 https://github.com/NLPchina/ansj_seg,经过测试发现效果不是很理想,不是拆的不准,而是商城的特殊性,使用分词类的工具会把中文拆的太零散,能搜到,但是搜的太多了!!! 🤦🏻‍♀️

然后我决定使用自定义词典定制分词,数据库分词使用关键词列表(庆幸自己没嫌麻烦把列表写出来了),而且它的好处是前端搜索入表,随着时间的推移,把搜索次数做成权重后,它的精确度会越来越高

于是我添加了耐克关键词,考虑到测试可能搜 nike women,nike女款, 耐克women,我对空格做了拆分,并且对子字符串做了进一步处理,于是变成了

在这里插入图片描述

regexp_like(field, '(耐克|nike).*女款', 'i')

到此结束,满足了产品,同时满足了测试, 当然这个方案还是不完善的,后期随着数据量增大,还要把这些关键词做缓存,提升查询速度。

下面是类型拆分代码,数据库部分不便放出来

 	private String breakWordWithSpace(String word) {
        String[] words = word.split("");
        String regexp = "[\\u0391-\\uFFE5]"; // 中文正则
        StringBuilder stringBuilder = new StringBuilder();
        boolean[] isChinese = new boolean[words.length];
        for (int i = 0; i < words.length; i++) {
            isChinese[i] = words[i].matches(regexp);
            if (i == 0) {
                stringBuilder.append(words[i]);
                continue;
            }
            if (isChinese[i - 1] != isChinese[i] && i != words.length - 1) {
                stringBuilder.append(" ");
            }
            stringBuilder.append(words[i]);
        }
        return stringBuilder.toString();
    }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值