博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring Boot 2.0 整合 ES 5 文章内容搜索实战
阅读量:6115 次
发布时间:2019-06-21

本文共 3141 字,大约阅读时间需要 10 分钟。

hot3.png

本章内容

文章内容搜索思路
搜索内容分词
搜索查询语句
筛选条件
分页、排序条件
小结

一、文章内容搜索思路

上一篇讲了在怎么在  2.0 上整合  5 ,这一篇聊聊具体实战。简单讲下如何实现文章、问答这些内容搜索的具体实现。实现思路很简单:

基于「短语匹配」并设置最小匹配权重值

哪来的短语,利用 IK 分词器分词
基于 Fiter 实现筛选
基于 Pageable 实现分页排序
这里直接调用搜索的话,容易搜出不尽人意的东西。因为内容搜索关注内容的连接性。所以这里处理方法比较 low ,希望多交流一起实现更好的搜索方法。就是通过分词得到很多短语,然后利用短语进行短语精准匹配。

ES 安装 IK 分词器插件很简单。第一步,在下载对应版本 。第二步,在 elasticsearch-5.5.3/plugins 目录下,新建一个文件夹 ik,把 elasticsearch-analysis-ik-5.5.3.zip 解压后的文件拷贝到 elasticsearch-5.1.1/plugins/ik 目录下。最后重启 ES 即可。

二、搜索内容分词

安装好 IK ,如何调用呢?

第一步,我这边搜搜内容会以 逗号 拼接传入。所以会先将逗号分割

第二步,在搜索词中加入自己本身,因为有些词经过 ik 分词后就没了... 这是个 bug

第三步,利用 AnalyzeRequestBuilder 对象获取 IK 分词后的返回值对象列表

第四步,优化分词结果,比如都为词,则保留全部;有词有字,则保留词;只有字,则保留字

核心实现代码如下:

/**     * 搜索内容分词     */    protected List
handlingSearchContent(String searchContent) { List
searchTermResultList = new ArrayList<>(); // 按逗号分割,获取搜索词列表 List
searchTermList = Arrays.asList(searchContent.split(SearchConstant.STRING_TOKEN_SPLIT)); // 如果搜索词大于 1 个字,则经过 IK 分词器获取分词结果列表 searchTermList.forEach(searchTerm -> { // 搜索词 TAG 本身加入搜索词列表,并解决 will 这种问题 searchTermResultList.add(searchTerm); // 获取搜索词 IK 分词列表 searchTermResultList.addAll(getIkAnalyzeSearchTerms(searchTerm)); }); return searchTermResultList; } /** * 调用 ES 获取 IK 分词后结果 */ protected List
getIkAnalyzeSearchTerms(String searchContent) { AnalyzeRequestBuilder ikRequest = new AnalyzeRequestBuilder(elasticsearchTemplate.getClient(), AnalyzeAction.INSTANCE, SearchConstant.INDEX_NAME, searchContent); ikRequest.setTokenizer(SearchConstant.TOKENIZER_IK_MAX); List
ikTokenList = ikRequest.execute().actionGet().getTokens(); // 循环赋值 List
searchTermList = new ArrayList<>(); ikTokenList.forEach(ikToken -> { searchTermList.add(ikToken.getTerm()); }); return handlingIkResultTerms(searchTermList); } /** * 如果分词结果:洗发水(洗发、发水、洗、发、水) * - 均为词,保留 * - 词 + 字,只保留词 * - 均为字,保留字 */ private List
handlingIkResultTerms(List
searchTermList) { Boolean isPhrase = false; Boolean isWord = false; for (String term : searchTermList) { if (term.length() > SearchConstant.SEARCH_TERM_LENGTH) { isPhrase = true; } else { isWord = true; } } if (isWord & isPhrase) { List
phraseList = new ArrayList<>(); searchTermList.forEach(term -> { if (term.length() > SearchConstant.SEARCH_TERM_LENGTH) { phraseList.add(term); } }); return phraseList; } return searchTermList; }

三、搜索查询语句

构造内容枚举对象,罗列需要搜索的字段,ContentSearchTermEnum 代码如下:

import lombok.AllArgsConstructor; @AllArgsConstructorpublic enum ContentSearchTermEnum {     // 标题    TITLE("title"),    // 内容    CONTENT("content");     /**     * 搜索字段     */    private String      name;     public String      getName() {             return name;    }     public void      setName(String name) {             this.name = name;    } }

循环进行「短语搜索匹配」搜索字段,然后并设置最低权重值为 1。核心代码如下:

转载于:https://my.oschina.net/u/3611008/blog/1860122

你可能感兴趣的文章
【随笔】工程师都是性情中人
查看>>
[译] React v16.8: 含有Hooks的版本
查看>>
“寒冬”下的金三银四跳槽季来了,帮你客观分析一下局面
查看>>
现代 JavaScript 函数库 usuallyjs 的安装和使用
查看>>
Leaflet-Develop-Guide
查看>>
Android Studio 导入 AOSP 源码
查看>>
React16时代,该用什么姿势写 React ?
查看>>
小程序上传图片到七牛云(支持多张上传,预览,删除)
查看>>
3分钟学会如何调度运营海量Redis系统
查看>>
浅析MySQL事务中的redo与undo
查看>>
iOS开发助手、ipa便捷上传工具!
查看>>
一文了解腾讯云数据库SaaS服务
查看>>
再见,BLE的那些坑!
查看>>
前端杂谈: 如何实现一个 Promise?
查看>>
一个超便捷的豆瓣电影Chrome插件
查看>>
C++ 学习笔记之——字符串和字符串流
查看>>
antd图标的本地化使用
查看>>
Vuejs 实战观书有感 C1
查看>>
UnixBench算分介绍
查看>>
GO的部分总结~
查看>>