前言 : 最近在看es,但是发现很少有从数据结构创建到应用的实例文章,所以决定自己写一个,共勉。
一 . 创建数据:
数据结构参考一下网站并稍加改动。
Elasticsearch 入门教程 - completion suggest实现搜索提示
1.因为测试数据中存在中文,所以第一步需要导入中文分词器 (ik分词器),在bin目录下执行以下命令,执行完成后重启es。
bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v6.5.3/elasticsearch-analysis-ik-6.5.3.zip
2 . 创建index(news_website),index的json结构格式如下。
{ "mappings": {
"news" : {
"properties" : {
"title" : {
"type": "text",
"analyzer": "ik_max_word",
"fields": {
"suggest" : {
"type" : "completion",
"analyzer": "ik_max_word"
}
}
},
"content": {
"type": "text",
"analyzer": "ik_max_word"
},
"core":{
"type":"double"
},
"group":{
"type":"text"
}
}
}
}
}
索引名称: news_website
索引Type: news
字段:title 标题,ik 细粒度分词,支持suggest推荐查询。
字段:content 详情
字段:core 详情
字段:group 分组
3.加入maven依赖
org.elasticsearch.client
elasticsearch-rest-high-level-client
6.5.3
org.apache.logging.log4j
log4j-api
2.7
org.apache.logging.log4j
log4j-core
2.7
4 . 创建客户端
public class InitClient {
public static RestHighLevelClient getClient() {
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200))
);
return client;
}
}5.创建索引的API
try (RestHighLevelClient client = InitClient.getClient();) {
// 创建索引名
CreateIndexRequest request = new CreateIndexRequest("news_website");
String source = "{\n" +
" \"properties\" : {\n" +
" \"title\" : {\n" +
" \"type\": \"text\",\n" +
" \"analyzer\": \"ik_max_word\",\n" +
" \"fields\": {\n" +
" \"suggest\" : {\n" +
" \"type\" : \"completion\",\n" +
" \"analyzer\": \"ik_max_word\"\n" +
" }\n" +
" }\n" +
" },\n" +
" \"content\": {\n" +
" \"type\": \"text\",\n" +
" \"analyzer\": \"ik_max_word\"\n" +
" },\n" +
"\t\"core\":{\n" +
"\t\"type\":\"double\"\n" +
"\t},\n" +
"\t\"group\":{\n" +
"\t\"type\":\"text\"\n" +
"\t}\n" +
" }\n" +
" }";
request.mapping("news", source, XContentType.JSON);
CreateIndexResponse createIndexResponse = client.indices().create(request);
//处理响应
boolean acknowledged = createIndexResponse.isAcknowledged();
boolean shardsAcknowledged = createIndexResponse.isShardsAcknowledged();
System.out.println("acknowledged :" + acknowledged + "| shardsAcknowledged: " + shardsAcknowledged);
} catch (IOException e) {
System.out.println(e);
}6.向索引中加入数据
try (RestHighLevelClient client = InitClient.getClient();) {
// 批量插入数据
BulkRequest bulkRequest = new BulkRequest();
// 获取数据
String[] datas = getData();
// 循环添加任务
for (int i = ; i < datas.length; i++) {
bulkRequest.add(
new IndexRequest("news_website", "news", i + 1 + "").
source(datas[i], XContentType.JSON)
);
}
BulkResponse response = null;
try {
//提交请求
response = client.bulk(bulkRequest, RequestOptions.DEFAULT);
} catch (ElasticsearchException e) {
logger.error(e);
}
// 返回请求状态
if (response != null) {
response.forEach(b -> {
DocWriteRequest.OpType opType = b.getOpType();
if (opType == DocWriteRequest.OpType.INDEX || opType == DocWriteRequest.OpType.CREATE) {
logger.info("创建数据成功!!!");
} else if (opType == DocWriteRequest.OpType.UPDATE) {
logger.info("更新数据成功!!!");
} else if (opType == DocWriteRequest.OpType.DELETE) {
logger.info("深处数据成功!!!");
}
});
}
} catch (IOException e) {
System.out.println(e);
}
// 创建数据
private static String[] getData() {
String[] strings = new String[5];
strings[] = "{\n" +
"\n" +
" \"title\": \"大话西游电影\",\n" +
"\n" +
" \"content\": \"大话西游的电影时隔20年即将在2017年4月重映\",\n" +
"\n" +
" \"core\" : 9.6,\n" +
"\n" +
" \"group\" : \"电影\"\n" +
"\n" +
"}";
strings[1] = "{\n" +
"\n" +
" \"title\": \"大话西游小说\",\n" +
"\n" +
" \"content\": \"某知名网络小说作家已经完成了大话西游同名小说的出版\",\n" +
"\n" +
" \"core\" : 8.7,\n" +
"\n" +
" \"group\" : \"小说\"\n" +
"\n" +
"}";
strings[2] = "{\n" +
"\n" +
" \"title\": \"大话西游手游\",\n" +
"\n" +
" \"content\": \"网易游戏近日出品了大话西游经典IP的手游,正在火爆内测中\",\n" +
"\n" +
" \"core\" : 7.8,\n" +
"\n" +
" \"group\" : \"游戏\"\n" +
"\n" +
"}";
strings[3] = "{\n" +
"\n" +
" \"title\": \"cxk唱跳rap\",\n" +
"\n" +
" \"content\": \"鸡你太美,鸡你实在实在太美!!!\",\n" +
"\n" +
" \"core\" : 7.8,\n" +
"\n" +
" \"group\" : \"游戏\"\n" +
"\n" +
"}";
strings[4] = "{\n" +
"\n" +
" \"title\": \"大话西游手游\",\n" +
"\n" +
" \"content\": \"大话西游手游2也出来了你期待不\",\n" +
"\n" +
" \"core\" : 7.8,\n" +
"\n" +
" \"group\" : \"游戏\"\n" +
"\n" +
"}";
return strings;
}7.遍历一下数据
try (RestHighLevelClient client = InitClient.getClient();) {
SearchRequest searchRequest = new SearchRequest("news_website");
searchRequest.types("news");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchRequest.source(searchSourceBuilder);
SearchResponse search = client.search(searchRequest, RequestOptions.DEFAULT);
// 处理返回值
SearchHits hits = search.getHits();
hits.forEach(hit -> {
String sourceAsString = hit.getSourceAsString();
System.out.println(sourceAsString);
System.out.println("---------------------------------");
});
} catch (IOException e) {
System.out.println(e);
}
二 . 高亮查询,我们要在查询中高亮显示客户查询关键字(小说)
try (RestHighLevelClient client = InitClient.getClient();) {
// 指定索引
SearchRequest request = new SearchRequest("news_website");
// 指定类型
request.types("news");
// 构建
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//构建查询体
MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("title", "小说");
searchSourceBuilder.query(matchQueryBuilder);
// 构建高亮设置
HighlightBuilder highlightBuilder = new HighlightBuilder();
//如果置为true,除非该字段的查询结果不为空才会被高亮
highlightBuilder.requireFieldMatch(false);
/*
单字段单样式展示
highlightBuilder.field("content").preTags("").postTags(" ");
*/
// 多字段不同样式高亮展示
HighlightBuilder.Field content = new HighlightBuilder.Field("content").preTags("" ).postTags("");
HighlightBuilder.Field title = new HighlightBuilder.Field("title").preTags("" ).postTags("");
highlightBuilder.field(content);
highlightBuilder.field(title);
searchSourceBuilder.highlighter(highlightBuilder);
request.source(searchSourceBuilder);
SearchResponse search = client.search(request, RequestOptions.DEFAULT);
SearchHits hits = search.getHits();
hits.forEach(hit -> {
Map<String, HighlightField> highlightFields = hit.getHighlightFields();
System.out.println(hit.getSourceAsString());
HighlightField highlight = highlightFields.get("content");
if (highlight != null) {
Text[] fragments = highlight.fragments();
if (fragments != null) {
for (int i = ; i < fragments.length; i++) {
System.out.println("content highlight :" + fragments[i]);
}
}
}
HighlightField highlight_title = highlightFields.get("title");
if (highlight != null) {
Text[] fragments = highlight_title.fragments();
if (fragments != null) {
for (int i = ; i < fragments.length; i++) {
System.out.println("title highlight :" + fragments[i]);
}
}
}
System.out.println("----------------------");
});
} catch (IOException e) {
System.out.println(e);
}
第一行是查询到的数据,第二行是在介绍中出现的小说字样并用
三,纠错查询,在查询中客户可能输入错误关键字,根据数据库中的数据给予适当修整
try (RestHighLevelClient client = InitClient.getClient()) {
SearchRequest request = new SearchRequest("news_website");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
SuggestBuilder suggestBuilder = new SuggestBuilder();
TermSuggestionBuilder termSuggestionBuilder =
SuggestBuilders.termSuggestion("title.suggest").text("cxk长跳rwp");
suggestBuilder.addSuggestion("title_suggest", termSuggestionBuilder);
searchSourceBuilder.suggest(suggestBuilder);
request.source(searchSourceBuilder);
SearchResponse search = client.search(request, RequestOptions.DEFAULT);
if (search.status().equals(RestStatus.OK)) {
Suggest suggest = search.getSuggest();
//获取建议结果
TermSuggestion title_suggest = suggest.getSuggestion("title_suggest");
title_suggest.getEntries().forEach(s -> {
System.out.println("您输入的是 : " + s.getText());
s.forEach(o -> {
System.out.println("你是不是要找 : " + o.getText());
});
});
}
} catch (IOException e) {
System.out.println(e);
}

四.查询补全,根据用户输入的头几个字猜后边想要输入的内容
try (RestHighLevelClient client = InitClient.getClient()) {
SearchRequest searchRequest = new SearchRequest("news_website");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
CompletionSuggestionBuilder suggestionBuilder = SuggestBuilders.completionSuggestion("title.suggest").prefix("大话西游");
// suggestionBuilder
SuggestBuilder suggestBuilder = new SuggestBuilder();
//起个别名
suggestBuilder.addSuggestion("title_suggest", suggestionBuilder);
// 装进source里
searchSourceBuilder.suggest(suggestBuilder);
searchRequest.source(searchSourceBuilder);
SearchResponse search = client.search(searchRequest, RequestOptions.DEFAULT);
if (RestStatus.OK.equals(search.status())) {
Suggest suggest = search.getSuggest();
CompletionSuggestion termSuggestion = suggest.getSuggestion("title_suggest");
termSuggestion.forEach(entity -> {
System.out.println(" text: " + entity.getText().toString());
entity.forEach(o -> {
System.out.println("suggest : " + o.getText().toString());
});
});
}
} catch (IOException e) {
System.out.println(e);
}
}
输入了‘大话西游’,会将数据中其他相关内容推荐出来。