引言

之前已经介绍了如何搭建elasticsearch服务端和简单的索引创建,和中文分词的支持。今天我们来说一说如何实现elasticsearch同时实现中文分词和pinyin分词。并且实现类似百度搜索栏的搜索建议的功能。

混合查询

实现混合查询有很多方式,这里介绍我认为是一个偷懒的方法,就是为你要拼音搜索的字段提供两个额外的字段,一个是全拼字段,一个是首字母缩写字段。我这里用的是官网的Employee的例子:

public class Employee implements Serializable {

private String firstName;

private String lastName;

private String pinyin;//firstName全拼

private String header;//firstName首字母缩写

private int age;

private String about;

private List interests;

....省略getter setter

接下来为index添加setting和mapping

XContentBuilder settings = XContentFactory.jsonBuilder();

settings.startObject()

.startObject("analysis")

.startObject("analyzer")

.startObject("ik_analyzer").field("tokenizer","ik_smart")

.endObject()

.endObject()

.endObject().endObject();

CreateIndexRequest createIndexRequest = new CreateIndexRequest(index).settings(settings);

CreateIndexResponse createIndexResponse = esClient.admin().indices().create(createIndexRequest).get();

logger.info("Index:{} created,response:{}", index, JSON.toJSON(createIndexResponse));

XContentBuilder builder = XContentFactory.jsonBuilder();

builder.startObject()

.startObject(type)

.startObject("properties")

.startObject("firstName").field("type", "string").field("analyzer","ik_smart")

/* .field("search_analyzer","ik_smart").field("preserve_separators",false) .field("preserve_position_increments",false)*/

.endObject()

.startObject("lastName").field("type", "string").field("analyzer","ik_smart")

.endObject()

.startObject("pinyin").field("type","string").field("analyzer","pinyin")

.startObject()

.startObject("header").field("type","string").field("analyzer","pinyin")

.startObject("about").field("type", "string").field("analyzer","ik_smart")

.endObject()

.startObject("interests").field("type", "string").field("analyzer","ik_smart")

.endObject()

.endObject()

.endObject()

.endObject();

PutMappingRequest putMappingRequest = new PutMappingRequest(index);

putMappingRequest.type(type);

putMappingRequest.source(builder);

PutMappingResponse putMappingResponse = esClient.admin().indices().putMapping(putMappingRequest).get();

logger.info("Mapping for `{}.{}` putted, response:{}", index, type, JSON.toJSON(putMappingResponse));

return true;

} catch (Exception e) {

logger.error("doCreateIndex", e);

return false;

}

添加几个测试用例,我这里直接用了批量插入索引的方法:

public Boolean bulkIndex(List jsonList){

if(esIndexTypes.get(index)==null) {

if(getMapping(index, indexType)) esIndexTypes.put(index,true);

}

BulkRequestBuilder bulkBuilder= esClient.prepareBulk();

for (String s : jsonList) {

IndexRequestBuilder requestBuilder = esClient.prepareIndex(index, indexType)

.setSource(s);

bulkBuilder.add(requestBuilder);

}

BulkResponse bulkResponse = bulkBuilder.execute().actionGet();

logger.info("index:{} bulk request,:response:{}",index,JSON.toJSON(bulkResponse));

return true;

}

@org.junit.Test

public void test(){

List list1 = new ArrayList<>(10000);

for (int i=0;i<10000;i++) {

Employee employee = new Employee();

employee.setFirstName("告白气球"+i);

employee.setPinyin("gaobaiqiqiu"+i);

employee.setHeader("gbqq");

employee.setLastName("周杰伦,日记");

employee.setAbout("呜啦啦啦火车笛\n" +

"\n" +

"随着奔腾的马蹄\n" +

"\n" +

"小妹妹吹着口琴\n" +

"\n" +

"夕阳下美了剪影\n" +

"\n" +

"我用子弹写日记,我泡妞看电影");

employee.setAge(18);

List list = new ArrayList();

list.add("喜欢打篮球");

list.add("在大晴天晒太阳");

list.add("泡妞看电影");

employee.setInterests(list);

list1.add(JSON.toJSONString(employee));

}

boolean index = esProxy.bulkIndex(list1);

}

最后直接搜gaobaiqiqiu或gbqq搜出来的数据像这样:

[{"firstName":"告白气球","lastName":"周杰伦,日记","pinyin":"gaobaiqiqiu","about":"呜啦啦啦火车笛\n\n随着奔腾的马蹄\n\n小妹妹吹着口琴\n\n夕阳下美了剪影\n\n我用子弹写日记,我泡妞看电影","header":"gbqq","interests":["喜欢打篮球","在大晴天晒太阳","泡妞看电影"],"age":18}]

如果直接搜告白搜出来的数据像这样:

[{"firstName":"告白气球","lastName":"周杰伦,日记","pinyin":"gaobaiqiqiu","about":"呜啦啦啦火车笛\n\n随着奔腾的马蹄\n\n小妹妹吹着口琴\n\n夕阳下美了剪影\n\n我用子弹写日记,我泡妞看电影","header":"gbqq","interests":["喜欢打篮球","在大晴天晒太阳","泡妞看电影"],"age":18}]

CompletionSuggestion查询建议

使用CompletionSuggestion时mapping需要改一下,实时推荐的字段type需要使用completion。

XContentBuilder builder = XContentFactory.jsonBuilder();

builder.startObject()

.startObject(type)

.startObject("properties")

.startObject("firstName").field("type", "completion").field("analyzer","ik_smart")

.field("search_analyzer","ik_smart").field("preserve_separators",false)

.field("preserve_position_increments",false)

.endObject()

.startObject("lastName").field("type", "string").field("analyzer","ik_smart")

.endObject()

.startObject("pinyin").field("type","string").field("analyzer","pinyin")

.startObject()

.startObject("header").field("type","string").field("analyzer","pinyin")

.startObject("about").field("type", "string").field("analyzer","ik_smart")

.endObject()

.startObject("interests").field("type", "string").field("analyzer","ik_smart")

.endObject()

.endObject()

.endObject()

.endObject();

查询的时候需要使用CompletionSuggestionBuilder.

public void searchSuggest(String str){

CompletionSuggestionBuilder suggestionBuilder = new CompletionSuggestionBuilder("firstName");

suggestionBuilder.analyzer("ik_smart");

suggestionBuilder.text(str);

SearchResponse response = esClient.prepareSearch(index).setTypes(indexType).setQuery(QueryBuilders.matchAllQuery())

.suggest(new SuggestBuilder().addSuggestion("my-suggest-1",suggestionBuilder)).get();

Suggest suggest= response.getSuggest();

CompletionSuggestion suggestion = suggest.getSuggestion("my-suggest-1");

List list = suggestion.getEntries();

for (int i = 0; i < list.size(); i++) {

List options = list.get(i).getOptions();

for (int j = 0; j < options.size(); j++) {

if (options.get(j) instanceof CompletionSuggestion.Entry.Option) {

CompletionSuggestion.Entry.Option op = options.get(j);

System.out.println(op.getScore()+"--"+op.getText());

}

}

}

}

你也可以使用restAPI:http://192.168.10.xxx:9200/megacorp/_search?pretty这里megacorp是indexName,

{ "size": 0,

"suggest": { "my-suggest-1": { "prefix": "someone li", "completion": { "field": "firstName" } } } }

查询出来的结果:

{

"took": 12,

"timed_out": false,

"_shards": { "total": 5, "successful": 5, "failed": 0 },

"hits": { "total": 0, "max_score": 0, "hits": [] },

"suggest": { "blog-suggest": [ { "text": "someone li", "offset": 0, "length": 10, "options": [ { "text": "someone like you", "_index": "megacorp", "_type": "employee", "_id": "AV_doqcXKY206Vs3lcCO", "_score": 1, "_source": { "about": "呜啦啦啦火车笛\n\n随着奔腾的马蹄\n\n小妹妹吹着口琴\n\n夕阳下美了剪影\n\n我用子弹写日记,我泡妞看电影", "age": 18, "firstName": "someone like you", "interests": [ "喜欢打篮球", "在大晴天晒太阳", "泡妞看电影" ], "lastName": "周杰伦,日记" } } ] } ] } }

es拼音分词 大帅哥_elasticsearch实现中文分词和拼音分词混合查询+CompletionSuggestion...相关推荐

  1. es拼音分词 大帅哥_elasticsearch 拼音+ik分词,spring data elasticsearch 拼音分词

    elasticsearch 自定义分词器 安装拼音分词器.ik分词器 下载源码需要使用maven打包 下载构建好的压缩包解压后放直接在elasticsearch安装目录下 plugins文件夹下,可以 ...

  2. es拼音分词 大帅哥_机器学习

    1. 赌场风云(背景介绍) 最近一个赌场的老板发现生意不畅,于是派出手下去赌场张望.经探子回报,有位大叔在赌场中总能赢到钱,玩得一手好骰子,几乎是战无不胜.而且每次玩骰子的时候周围都有几个保镖站在身边 ...

  3. es拼音分词 大帅哥_SpringBoot集成Elasticsearch 进阶,实现中文、拼音分词,繁简体转换...

    Elasticsearch 分词 分词分为读时分词和写时分词. 读时分词发生在用户查询时,ES 会即时地对用户输入的关键词进行分词,分词结果只存在内存中,当查询结束时,分词结果也会随即消失.而写时分词 ...

  4. es拼音分词 大帅哥_8 种架构设计模式优缺点大曝光 | 原力计划

    作者 | 程序员Tony责编 | 王晓曼出品 | CSDN博客什么是架构我想这个问题,十个人回答得有十一个答案,因为另外的那一个是大家妥协的结果,哈哈,我理解,架构就是骨架.人类的身体的支撑是主要由骨 ...

  5. 在linux中常用的shell备份脚本(波大帅哥)

    备份脚本: 备份网站内容 #!/bin/bash #指定运行的脚本shell #运行脚本要给用户执行权限 bakdir=/backup month=`date +%m` day=`date +%d` ...

  6. 我在日本小帅哥那学习了GCN

    事件起源 最近在研究GNN,看了些许GNN的东西,心想着光看不练门外汉啊!这可不行,于是我开始自己动手实现一个GCN识别,一想到整一个模型demo,那必少不了MINIST数据集,反正就移花接木大法(M ...

  7. 快的打车团队亮相“越策越开心”,帅哥美女惊艳全场

    近日,中国最大的叫车服务平台快的打车团队参与湖南经济电视台综艺节目"越策越开心"的录制,该节目由著名主持人汪涵.马可搭档,历经十年不衰,在湖南地区和视频网站上都有非常高的人气. 此 ...

  8. mysql中的汉字怎么转换_Mysql中文汉字转拼音的实现(每个汉字转换全拼)

    一.创建拼音对照表 代码如下: -- 创建汉字拼音对照临时表 CREATE TABLE IF NOT EXISTS `t_base_pinyin` ( `pin_yin_` varchar(255) ...

  9. python turtle怎么画海绵宝宝_画师绘制海绵宝宝性转拟人,派大星变小帅哥,又脑补一出甜蜜大戏...

    我已经工作了有一段时间了,但是我依然很喜欢看<海绵宝宝>这部动漫,每次看的时候都会笑得没心没肺,十分欢乐. 好羡慕海绵宝宝和派大星他们啊,海绵宝宝还要上班,有自己的理想和工作,派大星真的是 ...

最新文章

  1. 容器开启数据服务之旅系列(一):Kubernetes如何解自建PostgreSQL运维之痛
  2. confusion_matrix函数的使用
  3. oracle if-else sql 语句
  4. 管理mysql表知识点_数据库复习提纲(必考知识点整理)
  5. nginx 目录讲解
  6. 揭秘腾讯云最新音视频及融合通信技术实践
  7. servlet获取相对路径 绝对路径
  8. Android 升级JDK及配置问题。
  9. oracle如何取当前日期年月_Oracle获取当前年、月、日的方法
  10. 英伟达CUDA 10终于开放下载了
  11. 在python中print表示的数据类型是_在python中自己写的数据类型使用print无法输出每个元素...
  12. PHP直播源码js判断浏览器版本
  13. 理解条件随机场(转)
  14. 【matlab数字图像处理】数字图像处理中的坐标系
  15. 用PROTUES来演示80C51的的16MHZ晶振的示波器演示
  16. python中match用法_Python3.9.1中使用match方法详解
  17. mfc word转pdf
  18. matlab 求股票斜率,股票线性回归斜率公式
  19. oracle时间某年某月某日,sql getdate 咋办分享Sql的getDate()用法
  20. 笔记本电池电量保持在50~55%可延长电池寿命

热门文章

  1. MyEclipse快捷键Alt+Shift+s详解
  2. fluent文件怎么导入matlab,matlab读取fluent数据  转载
  3. webService序列化xml 以及去掉删除<string xmlns =“http://tempuri.org/”>
  4. 徐辉 北大计算机,徐辉的痛苦回忆_徐辉经历的那一段痛苦回忆
  5. opencv图像处理学习(六十八)——肤色检测
  6. Yii Framework 开发教程(35) Zii组件-Button示例
  7. 人教版 初步使用计算机 教案,人教版小学信息三上第5课益智游戏练技能教案与课件配套5篇...
  8. 6.shell之正则表达式
  9. 画出spi输出bdh数据总线时序图_单片机张毅刚课后习题答案.docx
  10. qcon_从QCon San Francisco 2008中学到的主要知识点和教训