一.项目包含的功能
1.高亮搜索;
2.词语自动补全;
3.分页查询;
4.复合查询;
5.对索引的增、删、改、查;
6.对文档的增、删、改;
7.搜索结果排序;
8.其他功能:文件读取(word、txt、pdf)
二.依赖环境版本
1.Elasticsearch 6.6.1;
2.jdk 1.8
3.前端分页插件:网上找的
4.elasticsearch-rest-high-level-client 6.6.1
5.spring boot 2.1.3
6.kibana 6.6.0
三.访问路径
1.项目路径:http://localhost:8080/searchTest.html
2.kibana路径:http://localhost:5601
3.Elasticsearch启动检测路径:http://localhost:9200/
四.页面效果
五.关键代码
package com.demo.elasticsearch.service;
import com.alibaba.fastjson.JSON;
import com.demo.elasticsearch.bean.FileBean;
import com.demo.elasticsearch.bean.FileBeanQuery;
import com.demo.elasticsearch.bean.FileMapping;
import com.demo.elasticsearch.util.AttachmentReader;
import org.apache.http.HttpHost;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest;
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.MultiSearchRequest;
import org.elasticsearch.action.search.MultiSearchResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.core.CountRequest;
import org.elasticsearch.client.core.CountResponse;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.suggest.Suggest;
import org.elasticsearch.search.suggest.SuggestBuilder;
import org.elasticsearch.search.suggest.SuggestBuilders;
import org.elasticsearch.search.suggest.SuggestionBuilder;
import org.elasticsearch.search.suggest.completion.CompletionSuggestion;
import org.springframework.stereotype.Service;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @Author: ln
* @Date: 2019/2/22 15:37
* @Description:
*/
@Service
public class ElasticsearchServiceImpl implements ElasticsearchService {
RestHighLevelClient client;
@Override
public String createIndex(String index, FileMapping mapping) throws IOException {
client = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http")));
CreateIndexRequest request = new CreateIndexRequest(index);
//索引配置
request.mapping("doc",
"keywordName", "type=keyword", "keywordAuthor", "type=keyword",
"suggestName", "type=completion", "suggestAuthor", "type=completion");
CreateIndexResponse createIndexResponse = client.indices().create(request, RequestOptions.DEFAULT);
client.close();
return JSON.toJSONString(createIndexResponse);
}
@Override
public String delIndex(String index) throws IOException {
client = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http")));
DeleteIndexRequest request = new DeleteIndexRequest(index);
AcknowledgedResponse deleteIndexResponse = client.indices().delete(request, RequestOptions.DEFAULT);
System.out.println(JSON.toJSONString(deleteIndexResponse));
client.close();
return JSON.toJSONString(deleteIndexResponse.isAcknowledged());
}
@Override
public String putDocument(String index, FileBean fileBean) throws IOException {
client = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http")));
File file = new File(fileBean.getFilePath());
String content = AttachmentReader.reader(fileBean.getFilePath());
fileBean.setContent(content);
fileBean.setName(file.getName());
IndexRequest indexRequest = new IndexRequest(index, "doc", fileBean.getId());
indexRequest.source(JSON.toJSONString(fileBean), XContentType.JSON);
IndexResponse response = client.index(indexRequest, RequestOptions.DEFAULT);
System.out.println(JSON.toJSONString(response));
client.close();
return JSON.toJSONString(response.status());
}
@Override
public String delDocument(String index, String id) throws IOException {
client = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http")));
DeleteRequest request = new DeleteRequest(index,"doc", id );
DeleteResponse deleteResponse = client.delete(request, RequestOptions.DEFAULT);
System.out.println(JSON.toJSONString(deleteResponse));
client.close();
return JSON.toJSONString(deleteResponse.status());
}
@Override
public String getDocument(String index, String id) throws IOException {
client = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http")));
GetRequest getRequest = new GetRequest(index,"doc", id );
GetResponse getResponse = client.get(getRequest, RequestOptions.DEFAULT);
System.out.println(JSON.toJSONString(getResponse));
client.close();
return JSON.toJSONString(getResponse);
}
@Override
public String keywordSearch(String index, String value,
int current, int size) throws IOException {
client = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http")));
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices(index);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//支持全词搜索的字段有:keywordName,keywordAuthor"
searchSourceBuilder.query(QueryBuilders.multiMatchQuery(value, "keywordName", "keywordAuthor"));
searchSourceBuilder.from(current);
searchSourceBuilder.size(size);
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
System.out.println(JSON.toJSONString(searchResponse));
//处理返回结果
List<Map<String, Object>> result = dealResult(searchResponse.getHits());
client.close();
return JSON.toJSONString(result);
}
@Override
public String multiSearch(String index, FileBeanQuery query,
int current, int size) throws IOException, IllegalAccessException {
client = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http")));
MultiSearchRequest request = new MultiSearchRequest();
for (Field field : query.getClass().getDeclaredFields()) {
field.setAccessible(true);
if(field.get(query) != null){
SearchRequest searchRequest = new SearchRequest(index);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.boolQuery().must(
QueryBuilders.matchQuery(field.getName(), field.get(query))));
searchRequest.source(searchSourceBuilder);
request.add(searchRequest);
}
}
MultiSearchResponse response = client.msearch(request, RequestOptions.DEFAULT);
System.out.println(JSON.toJSONString(response));
//返回结果处理
List<Map<String, Object>> result = new ArrayList<>();
MultiSearchResponse.Item[] multiSearchResponses = response.getResponses();
for (MultiSearchResponse.Item multiSearchRespons : multiSearchResponses) {
SearchHits hits = multiSearchRespons.getResponse().getHits();
for (SearchHit hit : hits.getHits()) {
Map<String, Object> map = hit.getSourceAsMap();
if(!result.contains(map)){
result.add(map);
}
}
}
client.close();
return JSON.toJSONString(result);
}
@Override
public String highlightSearch(String index, String value, int current, int size) throws IOException {
client = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http")));
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices(index);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//高亮,支持所有FileBean实体的字段
HighlightBuilder highlightBuilder = new HighlightBuilder();
FileBean fileBean = new FileBean();
String[] fieldNames = new String[fileBean.getClass().getDeclaredFields().length];
int i = 0;
for (Field f : fileBean.getClass().getDeclaredFields()) {
HighlightBuilder.Field highlight = new HighlightBuilder.Field(f.getName());
highlight.highlighterType("unified");
highlightBuilder.field(highlight);
fieldNames[i] = f.getName();
i++;
}
//设置高亮样式
highlightBuilder.preTags("<label style=\"color: red\">");
highlightBuilder.postTags("</label>");
//添加查询条件
searchSourceBuilder.highlighter(highlightBuilder);
searchSourceBuilder.query(QueryBuilders.multiMatchQuery(value, fieldNames));//搜索也支持所有FileBean实体的字段
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
System.out.println(JSON.toJSONString(searchResponse));
//获取高亮字段
List<Map<String, Object>> result = new ArrayList<>();
SearchHits hits = searchResponse.getHits();
for (SearchHit hit : hits.getHits()) {
Map<String, HighlightField> highlightFields = hit.getHighlightFields();
for (String fieldName : fieldNames) {
HighlightField highlight = highlightFields.get(fieldName);
System.out.println(fieldName);
if(highlight != null){
Text[] fragments = highlight.fragments();
String fragmentString = fragments[0].string();
System.out.println("高亮值:" + fragmentString);
Map<String, Object> map = hit.getSourceAsMap();
map.put(fieldName, fragmentString);
if(!result.contains(map)){
result.add(map);
}
}
}
}
client.close();
return JSON.toJSONString(result);
}
@Override
public String suggestSearch(String index, String value) throws IOException {
client = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http")));
SearchRequest searchRequest = new SearchRequest(index);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//查询补全词语
SuggestionBuilder completionName = SuggestBuilders.completionSuggestion("suggestName").text(value);
SuggestBuilder suggestBuilder = new SuggestBuilder();
suggestBuilder.addSuggestion("suggestName", completionName);
SuggestionBuilder completionAuthor = SuggestBuilders.completionSuggestion("suggestAuthor").text(value);
suggestBuilder.addSuggestion("suggestAuthor", completionAuthor);
searchSourceBuilder.suggest(suggestBuilder);
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
System.out.println(JSON.toJSONString(searchResponse));
//处理返回结果
Suggest suggest = searchResponse.getSuggest();
//支持自动补全搜索的字段有suggestName,suggestAuthor
CompletionSuggestion termSuggestion = suggest.getSuggestion("suggestName");
CompletionSuggestion termSuggestionAuthor = suggest.getSuggestion("suggestAuthor");
List<CompletionSuggestion.Entry> list = termSuggestion.getEntries();
list.addAll(termSuggestionAuthor.getEntries());
List<String> suggestList = new ArrayList<>();
for (CompletionSuggestion.Entry entry : list) {
for (CompletionSuggestion.Entry.Option option : entry) {
String suggestText = option.getText().string();
System.out.println("补全的词语:" + suggestText);
if(!suggestList.contains(suggestText)){
suggestList.add(suggestText);
}
}
}
client.close();
return JSON.toJSONString(suggestList);
}
@Override
public String searchAll(String index, int current, int size) throws IOException {
client = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http")));
SearchRequest searchRequest = new SearchRequest(index);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchAllQuery());
searchSourceBuilder.from(current);
searchSourceBuilder.size(size);
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
System.out.println(JSON.toJSONString(searchResponse));
//处理返回结果
SearchHits hits = searchResponse.getHits();
client.close();
return JSON.toJSONString(hits);
}
@Override
public String countQuery(String index) throws IOException {
client = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http")));
CountRequest countRequest = new CountRequest(index);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchAllQuery());
countRequest.source(searchSourceBuilder);
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.termQuery("user", "kimchy"));
countRequest.source(sourceBuilder);
CountResponse countResponse = client.count(countRequest, RequestOptions.DEFAULT);
long count = countResponse.getCount();
return count + "";
}private List<Map<String, Object>> dealResult(SearchHits hits){
List<Map<String, Object>> result = new ArrayList<>();
for (SearchHit hit : hits.getHits()) {
Map<String, Object> map = hit.getSourceAsMap();
result.add(map);
}
return result;
}
}
注:完整Demo代码整理后贴出。