在Java项目中使用Elasticsearch 6.x (一)对索引的增删改查

一.项目包含的功能
    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代码整理后贴出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值