Java 使用 nlp-lang 包实现基于内存的搜索提示

最近有在研究希望能够实现一个搜索框的智能搜索提示,几经辗转找到了这个包。
在这里插入图片描述

<!-- https://mvnrepository.com/artifact/org.nlpcn/nlp-lang -->
<groupId>org.nlpcn</groupId>
<artifactId>nlp-lang</artifactId>
<version>1.7.9</version>

基于这个包可以帮助我们实现一个基于内存的关键字提示功能。

介绍

核心类为 org.nlpcn.commons.lang.index.MemoryIndex,通过这个类可以帮助我们实现一个简单的倒排索引。在不考虑性能的情况下,这个类可以帮助我们实现一个开箱即用的倒排索引。

这里我们主要是针对字符串实现智能提示,编写一个封装:

public class SearchTemplate {
	/**
	 * 索引
	*/
    private final MemoryIndex<String> index;
    public SearchTemplate() {
        index = new MemoryIndex<>();
    }
    /**
     * 获取提示
     * @param key
     * @return
     */
    public Collection<String> suggest(String key) {
    	// 智能提示,允许错别字
        return index.smartSuggest(key);
    }
    /**
     * 添加记录
     * @param record 记录
     */
    public void add(String record) {
    	// 获取记录的拼音,并为记录索引
        String pinyin = String.join("", Pinyin.pinyin(record));
        // 获取记录的首字母,并为记录索引
        String firstChar = String.join("", Pinyin.firstChar(record));
        index.addItem(record, record, pinyin, firstChar);
    }
}

然后在方法中添加记录,后调用方法suggest获取建议:

public static void main(String[] args) {
    List<String> list = Arrays.asList("中国", "中华人民共和国", "美国", "我爱中国", "我是中国人", "漂亮国", "中世纪的世界", "天堂");
    SearchTemplate searchTemplate = new SearchTemplate();
    // 将记录遍历并添加的倒排索引中
    list.forEach(searchTemplate::add);
    // 获取搜索结果
    System.out.println(searchTemplate.suggest("zhong")); //[中国, 我爱中国, 我是中国人, 中世纪的世界, 中华人民共和国]
    System.out.println(searchTemplate.suggest("国")); //[中国, 美国, 漂亮国, 我爱中国, 我是中国人, 中华人民共和国, 天堂, 中世纪的世界]
    System.out.println(searchTemplate.suggest("我")); //[我爱中国, 我是中国人]
    System.out.println(searchTemplate.suggest("wa")); //[我爱中国]
    System.out.println(searchTemplate.suggest("shijie")); //[中世纪的世界]
}

由于我在封装 MemoryIndex 的时候使用到了 smartSuggest 这个方法相较于 suggest会通过查询的关键字尽可能的去匹配记录,所以你会发现有的结果与你查询的关键字完全对不上。

比如当我以 “国” 为关键字进行搜索的时候,会出现 “天堂”,“中世纪的世界” 这样记录中完全不包含 “国” 的记录。而 MemoryIndex 背后的搜索逻辑为:

  1. 使用 “国” 进行搜索,获取搜索到的结果
  2. 如果结果数量少于配置的数量,
    则获取 “国” 的全拼 “guo” 并以此作为关键字获取相匹配的记录,
    添加到搜索结果中
  3. 如果结果数量任然小于配置的数量
    则获取 “国” 的拼音首字母 “g” 并以此作为关键字获取相匹配的记录
    添加到搜索结果中

最终得到的结果就是由于记录 “天堂” 的全拼 “taintang” 和 “中世纪的世界” 的全拼 “zhongshijideshijei” 中包含 “g”,因此他们也在搜索结果中。

这里实现的功能其实很简单,而基于内存的搜索提示其实相当占用内存,比如上述的逻辑,我只输入了 7 条记录,但是 MemoryIndex 处理后保存的记录数就已经达到了惊人的 743 条结果了,这是因为MemoryIndex 会将每一种输入可能都处理成为了一条记录并保存下来,因此这样的搜索提示我们实际上是不能把它放到线上去的,但这种实现原理也为我们的开发提供了一种参考。

关于 nlp-lang 包,它提供了相当多的工具,能够帮助我们很好的处理文本,有机会可以好好研究下。

与这个包相关的还有一个

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

这是一个可以用于实现中文分词的工具,日后也可以好好研究下。

参考资料

java 汉字拼音搜索
NLPchina/ansj_seg
nlp 项目常用工具包

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值