RestHighLevelClient实现搜索引擎


一、前言

海量数据的情况下,SQL中的模糊查询%s%会导致索引失效,但是业务场景需要根据某些字段进行查询。

搜索引擎会为数据添加索引,并且支持模糊查询,范围查询,精确查询
所以海量数据的全文搜索,最好是用搜索引擎来进行实现。
以下是开源搜索引擎elasticsearch的 RestHighLevelClient简单工具实现,添加数据获取数据全部使用json操作

二、使用步骤

1.pom文件和配置文件

	<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.2</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

	<dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>7.14.0</version>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch</groupId>
            <artifactId>elasticsearch</artifactId>
            <version>7.14.0</version>
        </dependency>
elasticsearch.ip=127.0.0.1
elasticsearch.port=9200

2.配置类

package com.mabo.elasticsearch;

import org.apache.http.HttpHost;
import org.elasticsearch.client.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ElasticSearchConfig {
    @Value("${elasticsearch.ip}")
    private String ip;
    @Value("${elasticsearch.port}")
    private String port;
    /**
     * 创建单例模式的RequestOptions,使得所有请求共用
     */
    public static final RequestOptions COMMON_OPTIONS;
    static {
        RequestOptions.Builder builder = RequestOptions.DEFAULT.toBuilder();
        COMMON_OPTIONS = builder.build();
    }

    @Bean
    public RestHighLevelClient client() {
        RestClientBuilder builder=RestClient.builder(new HttpHost(ip, Integer.valueOf(port), "http"));
        RestHighLevelClient client = new RestHighLevelClient(builder);
        return client;
    }
}

3.工具类

package com.roc.core.utils.elasticsearch;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.roc.core.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
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.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.util.Map;

@Component
@Slf4j
public class ElasticsearchUtils {

    @Autowired
    private RestHighLevelClient restHighLevelClient;


    public String addDocument(JSONObject params,String index,String idName) throws IOException {
        IndexRequest indexRequest = new IndexRequest(index);
        indexRequest.id(params.getString(idName));
        // 将我们的数据放入请求 json
        indexRequest.source(params, XContentType.JSON);
        // 客户端发送请求
        IndexResponse index1 = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
        /**
         * @Description : CREATED 新增成功
         * OK,更新成功
         * @Author : mabo
         */
        return index1.status().toString();
    }

    /**
     * 根据id
     * 获取文档
     * @throws IOException
     */
    public JSONObject getDocumentById(String index, String id) {
        GetRequest getRequest = new GetRequest(index, id);
        GetResponse getResponse = null;
        try {
            getResponse = restHighLevelClient.get(getRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            log.error(e.getMessage(),e);
            return null;
        }
        Map<String, Object> sourceAsMap = getResponse.getSourceAsMap();
        if (sourceAsMap!=null){
            return new JSONObject(sourceAsMap);
        }
        else {
            return null;
        }

    }
    /**
     * 获取文档
     * @throws IOException
     */
    public JSONArray getDocument(int from,int size,String index) throws IOException {
        SearchRequest searchRequest=new SearchRequest(index);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.from(from).size(size);
        searchSourceBuilder.query(QueryBuilders.matchAllQuery());
        searchRequest.source(searchSourceBuilder);
        SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        JSONArray array = new JSONArray();
        SearchHits hits = response.getHits();
        for (SearchHit searchHit : hits) {
            Map<String, Object> sourceAsMap = searchHit.getSourceAsMap();
            JSONObject json = new JSONObject(sourceAsMap);
            array.add(json);
        }
        return array;
    }

    /**
     * 删除文档
     */
    public boolean deleteDodument(String index, String id) throws IOException {
        JSONObject documentById = getDocumentById(index, id);
        if (documentById ==null){
            return true;
        }
        DeleteRequest deleteRequest = new DeleteRequest(index, id);
        DeleteResponse delete = restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
        String s = delete.status().toString();
        if (s.equals("OK")){
            return true;
        }
        else {
            return false;
        }
    }

    /**
     * 删除索引
     * @param index
     * @return
     * @throws IOException
     */
    public boolean deleteAllDodument(String index) throws IOException {
        DeleteIndexRequest deleteRequest = new DeleteIndexRequest(index);
        AcknowledgedResponse delete = restHighLevelClient.indices().delete(deleteRequest, RequestOptions.DEFAULT);
        return delete.isAcknowledged();
    }


    /**
     * @Description : 模糊查询
     * @Author : mabo
     */
    public JSONArray fuzzySearch(int from,int size,String index, String value, String... fieldName) throws IOException {
        SearchRequest searchRequest=new SearchRequest(index);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.from(from).size(size);
        searchSourceBuilder.query(QueryBuilders.multiMatchQuery(value,fieldName));
        searchRequest.source(searchSourceBuilder);
        SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        JSONArray array = new JSONArray();
        SearchHits hits = response.getHits();
        for (SearchHit searchHit : hits) {
            Map<String, Object> sourceAsMap = searchHit.getSourceAsMap();
            JSONObject json = new JSONObject(sourceAsMap);
            array.add(json);
        }
        return array;
    }
    /**
     * @Description : 范围查询
     * @Author : mabo
     */
    public JSONArray rangeSearch(int from,int size,String index, String max,String min, String fieldName) throws IOException {
        SearchRequest searchRequest=new SearchRequest(index);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.from(from).size(size);
        searchSourceBuilder.query(QueryBuilders.rangeQuery(fieldName).from(min).to(max));
        searchRequest.source(searchSourceBuilder);
        SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        JSONArray array = new JSONArray();
        SearchHits hits = response.getHits();
        for (SearchHit searchHit : hits) {
            Map<String, Object> sourceAsMap = searchHit.getSourceAsMap();
            JSONObject json = new JSONObject(sourceAsMap);
            array.add(json);
        }
        return array;
    }

    /**
     * @Description : 模糊查询
     * @Author : mabo
     */
    public JSONArray fuzzySearchSeal(int from,int size,String index, String value, String fieldName) throws IOException {
        SearchRequest firstSearchRequest=new SearchRequest(index);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.from(from).size(size);
        searchSourceBuilder.query(QueryBuilders.multiMatchQuery(value,"goodName","detail"));
        firstSearchRequest.source(searchSourceBuilder);
        //搜索
        SearchResponse search = restHighLevelClient.search(firstSearchRequest, RequestOptions.DEFAULT);
        JSONArray array = new JSONArray();
        SearchHit[] hits =  search.getHits().getHits();
        for (SearchHit searchHit : hits) {
            Map<String, Object> sourceAsMap = searchHit.getSourceAsMap();
            JSONObject json = new JSONObject(sourceAsMap);
            array.add(json);
        }
        return array;
    }

    /**
     * @Description : 多条件模糊查询
     * @Author : mabo
     */
    public JSONArray fuzzyMultiSearch(int from,int size, String goodName,
                                      Double latitudeMin,Double latitudeMax,
                                      Double longitudeMin,Double longitudeMax,
                                      Double sealMoneyMin,Double sealMoneyMax) throws IOException {
        //设置索引
        SearchRequest searchRequest = new SearchRequest("sealinfo");
        //构建查询
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolBuilder = QueryBuilders.boolQuery();

        RangeQueryBuilder latitudeBuilder = QueryBuilders.rangeQuery("latitude").from(latitudeMin).to(latitudeMax);
        RangeQueryBuilder longitudeBuilder = QueryBuilders.rangeQuery("longitude").from(longitudeMin).to(longitudeMax);
        boolBuilder = boolBuilder.must(latitudeBuilder);
        boolBuilder = boolBuilder.must(longitudeBuilder);
        if (!StringUtils.isBlank(goodName)){
            MultiMatchQueryBuilder goodNameBuilder = QueryBuilders.multiMatchQuery(goodName, "goodName", "detail");
            boolBuilder = boolBuilder.must(goodNameBuilder);
        }
        if (sealMoneyMin>0&&sealMoneyMax>0){
            RangeQueryBuilder sealMoney = QueryBuilders.rangeQuery("sealMoney").from(sealMoneyMin).to(sealMoneyMax);
            boolBuilder = boolBuilder.must(sealMoney);
        }
        sourceBuilder.from(from).size(size);
        sourceBuilder.query(boolBuilder);
        searchRequest.source(sourceBuilder);
        //发送请求
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest,RequestOptions.DEFAULT);
        JSONArray array = new JSONArray();
        SearchHits hits = searchResponse.getHits();
        for (SearchHit hit : hits) {
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            JSONObject json = new JSONObject(sourceAsMap);
            String allow = json.getString("allow");
            String tradeType = json.getString("tradeType");
            if (allow.equals("1")&&tradeType.equals("2")){
                array.add(json);
            }
        }
        return array;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值