一、先摆需求:

1、中文搜索、英文搜索、中英混搜   如:“南京东路”,“cafe 南京东路店”

2、全拼搜索、首字母搜索、中文+全拼、中文+首字母混搜   如:“nanjingdonglu”,“njdl”,“南京donglu”,“南京dl”,“nang南东路”,“njd路”等等组合

3、简繁搜索、特殊符号过滤搜索   如:“龍馬”可通过“龙马”搜索,再比如 L.G.F可以通过lgf搜索,café可能通过cafe搜索

4、排序优先级为: 以关键字开头>包含关键字

二、生产效果图:

三、实现

1、索引设计

为搜索字段建立不同类型的索引,有全拼索引、首字母简写索引、Ngram索引以及IK索引,从各个角度分别击破,然后通过char-filter进行特殊符号与简繁转换。

1.建立settingsPUT /enterpriseextend
{"settings": {"analysis": {"filter": {"edge_ngram_filter": {"type": "edge_ngram","min_gram": 1,"max_gram": 50},"pinyin_simple_filter": {"type": "pinyin","keep_first_letter": true,"keep_separate_first_letter": false,"keep_full_pinyin": false,"keep_original": false,"limit_first_letter_length": 50,"lowercase": true},"pinyin_full_filter": {"type": "pinyin","keep_first_letter": false,"keep_separate_first_letter": false,"keep_full_pinyin": true,"none_chinese_pinyin_tokenize": true,"keep_original": false,"limit_first_letter_length": 50,"lowercase": true}},"char_filter": {"charconvert": {"type": "mapping","mappings_path": "char_filter_text.txt"}},"tokenizer": {"ik_max_word": {"type": "ik_max_word","use_smart": true}},"analyzer": {"ngramIndexAnalyzer": {"type": "custom","tokenizer": "keyword","filter": ["edge_ngram_filter","lowercase"],"char_filter": ["charconvert"]},"ngramSearchAnalyzer": {"type": "custom","tokenizer": "keyword","filter": ["lowercase"],"char_filter": ["charconvert"]},"ikIndexAnalyzer": {"type": "custom","tokenizer": "ik_max_word","char_filter": ["charconvert"]},"ikSearchAnalyzer": {"type": "custom","tokenizer": "ik_max_word","char_filter": ["charconvert"]},"pinyiSimpleIndexAnalyzer": {"tokenizer": "keyword","filter": ["pinyin_simple_filter","edge_ngram_filter","lowercase"]},"pinyiSimpleSearchAnalyzer": {"tokenizer": "keyword","filter": ["pinyin_simple_filter","lowercase"]},"pinyiFullIndexAnalyzer": {"tokenizer": "keyword","filter": ["pinyin_full_filter","lowercase"]},"pinyiFullSearchAnalyzer": {"tokenizer": "keyword","filter": ["pinyin_full_filter","lowercase"]}}}}
}2.建立mappingPUT enterpriseextend/_mapping/enterpriseextend
{"properties": {"id": {"type": "long"},"entName": {"type": "text", "analyzer": "ikIndexAnalyzer","fields": {"ngram": {"type": "text", "analyzer": "ngramIndexAnalyzer"},"SPY": {"type": "text", "analyzer": "pinyiSimpleIndexAnalyzer"},"FPY": {"type": "text", "analyzer": "pinyiFullIndexAnalyzer"}}},"serviceFinanceEntType": {"type": "text","analyzer": "ik_max_word","fields": {"keyword": {"type": "keyword","ignore_above": 256}}},"serviceSupport": {"type": "text","analyzer": "ik_max_word","fields": {"keyword": {"type": "keyword","ignore_above": 256}}},"serviceEntRat": {"type": "text","analyzer": "ik_max_word","fields": {"keyword": {"type": "keyword","ignore_above": 256}}}}
}

拼音插件的使用请参考:https://github.com/medcl/elasticsearch-analysis-pinyin

2、搜索构建

以下是dao层搜索实现代码(非完整代码,只摘录核心部分,主要是思路):


package com.boao.platform.search.dao;import com.boao.platform.common.util.ChineseToPinYinUtil;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;import java.io.IOException;
import java.util.concurrent.TimeUnit;@Repository
public class EnterpriseExtendRecommendRepository {@Autowiredprivate RestHighLevelClient client;//索引库名称private static final String INDEX = "enterpriseextend";//文档类型private static final String TYPE = "enterpriseextend";public SearchResponse getList(String words,int pageNo,int pageSize){// 这个sourcebuilder就类似于查询语句中最外层的部分。包括查询分页的起始,// 查询语句的核心,查询结果的排序,查询结果截取部分返回等一系列配置SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();// 结果开始处sourceBuilder.from((pageNo-1)*pageSize);// 查询结果终止处sourceBuilder.size(pageSize);// 查询的等待时间sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));//执行查询sourceBuilder.query(chineseAndPinYinSearch(words));System.out.println(sourceBuilder);//指定索引库和类型SearchRequest searchRequest = new SearchRequest(INDEX);searchRequest.types(TYPE);searchRequest.source(sourceBuilder);try {return client.search(searchRequest);} catch (IOException e) {e.printStackTrace();}return null;}//中文、拼音混合搜索private QueryBuilder chineseAndPinYinSearch(String words){//使用dis_max直接取多个query中,分数最高的那一个query的分数即可DisMaxQueryBuilder disMaxQueryBuilder=QueryBuilders.disMaxQuery();/*** 纯中文搜索,不做拼音转换,采用edge_ngram分词(优先级最高)* 权重* 5*/QueryBuilder normSearchBuilder=QueryBuilders.matchQuery("entName.ngram",words).analyzer("ngramSearchAnalyzer").boost(5f);/*** 拼音简写搜索* 1、分析key,转换为简写  case:  南京东路==>njdl,南京dl==>njdl,njdl==>njdl* 2、搜索匹配,必须完整匹配简写词干* 3、如果有中文前缀,则排序优先* 权重*1*/String firstChar = ChineseToPinYinUtil.ToFirstChar(words);TermQueryBuilder pingYinSampleQueryBuilder = QueryBuilders.termQuery("entName.SPY", firstChar);/*** 拼音简写包含匹配,如 njdl可以查出 "城市公牛 南京东路店",虽然非南京东路开头* 权重*0.8*/QueryBuilder  pingYinSampleContainQueryBuilder=null;if(firstChar.length()>1){pingYinSampleContainQueryBuilder=QueryBuilders.wildcardQuery("entName.SPY", "*"+firstChar+"*").boost(0.8f);}/*** 拼音全拼搜索* 1、分析key,获取拼音词干   case :  南京东路==>[nan,jing,dong,lu],南京donglu==>[nan,jing,dong,lu]* 2、搜索查询,必须匹配所有拼音词,如南京东路,则nan,jing,dong,lu四个词干必须完全匹配* 3、如果有中文前缀,则排序优先* 权重*1*/QueryBuilder pingYinFullQueryBuilder=null;if(words.length()>1){pingYinFullQueryBuilder=QueryBuilders.matchPhraseQuery("entName.FPY", words).analyzer("pinyiFullSearchAnalyzer");}/*** 完整包含关键字查询(优先级最低,只有以上四种方式查询无结果时才考虑)* 权重*0.8*/QueryBuilder containSearchBuilder=QueryBuilders.matchQuery("entName", words).analyzer("ikSearchAnalyzer").minimumShouldMatch("100%");disMaxQueryBuilder.add(normSearchBuilder).add(pingYinSampleQueryBuilder).add(containSearchBuilder);//以下两个对性能有一定的影响,故作此判定,单个字符不执行此类搜索if(pingYinFullQueryBuilder!=null){disMaxQueryBuilder.add(pingYinFullQueryBuilder);}if(pingYinSampleContainQueryBuilder!=null){disMaxQueryBuilder.add(pingYinSampleContainQueryBuilder);}return disMaxQueryBuilder;}}

注:以上JAVA示例代码皆以 elasticsearch官方推荐的 Java High Level REST Client 6.2.2 为基础。

定制特殊符号及简繁转换文本:char_filter_text.txt,由于文件有点长,以下是部分内容,参考格式即可。

à=>a
á=>a
â=>a
ä=>a
À=>a
Â=>a
Ä=>a
è=>e
é=>e
ê=>e
ë=>e
È=>e
É=>e
Ê=>e
Ë=>e
î=>i
ï=>i
Î=>i
Ï=>i
ô=>o
ö=>o
Ô=>o
Ö=>o
ù=>u
û=>u
ü=>u
Ù=>u
Û=>u
Ü=>u
ç=>c
œ=>c
&=>
^=>
.=>
·=>
-=>
'=>
’=>
‘=>
/=>
醯壶=>醯壶
屢顧爾僕=>屡顾尔仆
見=>见
往裡=>往里
置言成範=>置言成范
捲動=>卷动
規=>规
齣電視=>出电视
覎=>觃
後堂=>后堂

elasticsearch 6.2.2 搜索推荐系列(三)之高级搜索查询实现( 中文+拼音+首字母+简繁转换+特殊符号过滤)相关推荐

  1. Elasticsearch高级搜索排序( 中文+拼音+首字母+简繁转换+特殊符号过滤)(示例代码)

    简介  这篇文章主要介绍了Elasticsearch高级搜索排序( 中文+拼音+首字母+简繁转换+特殊符号过滤)(示例代码)以及相关的经验技巧,文章约21106字,浏览量320,点赞数5,值得参考! ...

  2. querybuilder 排序_Elasticsearch高级搜索排序( 中文+拼音+首字母+简繁转换+特殊符号过滤)...

    一.先摆需求: 1.中文搜索.英文搜索.中英混搜   如:"南京东路","cafe 南京东路店" 2.全拼搜索.首字母搜索.中文+全拼.中文+首字母混搜   如 ...

  3. Elasticsearch-高级搜索(拼音|首字母|简繁|二级搜索)

    需求: 中文搜索.英文搜索.中英混搜 全拼搜索.首字母搜索.中文+全拼.中文+首字母混搜 简繁搜索 二级搜索(对第一次搜索结果,再进行搜索) 一.ES相关插件 IK分词: GitHub - medcl ...

  4. [Emuelec]支持中文拼音首字母搜索,但不显示拼音首字母

    1.在gamelist.xml中添加字段sortname,将游戏名(不带拼音首字母的名字)填入其中 2.在游戏系统选择文本筛选模式为"按排序名筛选" 查看结果,字幕尾巴不见了 对应 ...

  5. 在PostgreSQL中实现按拼音、汉字、拼音首字母搜索的例子

    在PostgreSQL中实现按拼音.汉字.拼音首字母搜索的例子 作者 digoal 日期 2016-11-09 标签 PostgreSQL , 拼音 , 中文分词 , tsvector , 拼音首字母 ...

  6. MySQL拼音首字母查询(支持三个中文以内的查询)

    #参考这篇博客:http://blog.csdn.net/naruto1021/article/details/17502783,不过这个只支持查询一个中文字母,这是不太符合我的要求,改写如下: 如果 ...

  7. mysql 拼音首字母_MySQL拼音首字母查询(支持三个中文以内的查询)

    #参考这篇博客:http://blog.csdn.net/naruto1021/article/details/17502783,不过这个只支持查询一个中文字母,这是不太符合我的要求,改写如下: 如果 ...

  8. 自然语言处理技术(NLP)在推荐系统中的应用 原2017.06.29人工智能头条 作者: 张相於,58集团算法架构师,转转搜索推荐部负责人,负责搜索、推荐以及算法相关工作。多年来主要从事推荐系统以及机

    自然语言处理技术(NLP)在推荐系统中的应用 原2017.06.29人工智能头条 作者: 张相於,58集团算法架构师,转转搜索推荐部负责人,负责搜索.推荐以及算法相关工作.多年来主要从事推荐系统以及机 ...

  9. Android 利用AutoCompleteTextView实现模糊搜索功能,搜索结果自动提示,识别拼音首字母并转汉字提示

    这里说一下怎么利用 Android 的 AutoCompleteTextView 控件实现模糊搜索功能,AutoCompleteTextView 自带自动提示功能.如果 对自动提示的布局自定义要求比较 ...

最新文章

  1. mysqldump 导入数据库可能遇到错误
  2. android之View坐标系(view获取自身坐标的方法和点击事件中坐标的获取)
  3. MapReduce源码分析之JobSplitWriter
  4. python中字典的常用函数_python中得字典和常用函数总结
  5. PHP专题-开发基础(七)
  6. 【听歌】GDB入门教程之查看函数调用堆栈
  7. 信奥中的数学:孙子定理 中国剩余定理
  8. ajax鼠标滚动请求 或 手机往下拉请求
  9. java native 开发环境搭建_Java3D 集成开发环境部署与配置(含实例)
  10. 正态分布的前世今生:正态魅影
  11. 一段、两段及三段式状态机的写法——售货机的verilog实现
  12. 4k纸是几厘米乘几厘米_4K纸是多大?
  13. JAVA实现汉字转换为拼音 自动识别常用多音字 JPinyin
  14. python项目-Python 的练手项目有哪些值得推荐?
  15. HIT 软件构造 lab3实验报告
  16. Java基础 项目实例五 简易聊天系统
  17. 打开网页弹出“出现了运行时间错误,是否要调试”的解决办法
  18. (无导师学习神经网络)竞争神经网络、SOFM神经网络
  19. 推荐几本学习Go语言的书
  20. jquery判断文本框输入的是非数字内容(交流QQ群:452892873)

热门文章

  1. 如何顺利申请ISO9001质量管理体系认证?
  2. 人像抠图怎么操作?这个方法掌握了吗
  3. 文字转语音工具—百度语音广播
  4. redis常用查询操作
  5. 自动获取网页的icon地址,个人博客,个人导航,java
  6. [java]01受检异常和非受检异常的区别
  7. es中 content tier.和 hot tier有什么区别于联系
  8. 95后毕业生求职:不问工资,关心有无健身房下午茶
  9. 常用USB转串口工具, win10上使用的解决方案
  10. 徒手创建电脑快捷方式