Springboot整合Elasticsearch 7.X以及相关API的使用

下面是关于相关Elasticsearch的API功能是一些增删查改功能,到时可根据自己需求进行修改

  1. 在idea中创建springboot项目,并选中Elasticsearch依赖
    在这里插入图片描述
    在这里插入图片描述
  2. 自定义elasticsearch版本,保证跟本地一致(由于我本机安装的是7.X版本的),同时再添加上相关json依赖。
    在这里插入图片描述
    在这里插入图片描述
	<properties>
        <java.version>1.8</java.version>
        <!--自定义es版本依赖,保证和本地一致-->
        <elasticsearch.version>7.6.1</elasticsearch.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.26</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>
  1. 在application.properties添加上相关的配置
elasticsearch.hostname:127.0.0.1
elasticsearch.port:9200
elasticsearch.scheme:http
  1. 同时创建一个config包,并在该包下创建elasticSearchConfig.java的配置类
@Configuration
public class elasticSearchConfig {
    @Value("${elasticsearch.hostname}")
    private String hostname;
    @Value("${elasticsearch.port}")
    private int port;
    @Value("${elasticsearch.scheme}")
    private String scheme;

    @Bean
    public RestHighLevelClient restHighLevelClient(){
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(new HttpHost(hostname,port,scheme)));
        return client;
    }
}
  1. 创建service包,并在该包下创建EsSearchService接口,用于实现Elasticsearch的相关功能,同时在service包下再创建一个Impl包,并在该包下创建EsSearchServiceImpl.java.(下面的索引可以理解为建立一个表,然后文档可以理解为给这个表中添加每一行数据)
    EsSearchService.java
public interface EsSearchService {

    /**
     * 创建索引
     * @param index  索引的名称
     * @return
     */
    boolean CreateIndex(String index) throws IOException;

    /**
     * 获取索引(一个索引相当于一个数据库,你只能判断索引是否存在)
     * @param index 索引名
     * @return
     * @throws IOException
     */
    boolean isExit(String index) throws IOException;

    /**
     * 删除索引
     * @param index
     * @return
     */
    boolean delete(String index) throws IOException;

    /**
     * 添加文档
     * @param index 需要添加文档的索引名称
     * @param object 需要添加文档的内容(这里传入的是对象)
     * @return
     */
    boolean addDocument(String index, String id, Object object) throws IOException;

    /**
     * 获取文档,判断是否存在 /index/doc/id
     * @param index
     * @param id
     * @return
     */
    boolean isdocuexit(String index, String id) throws IOException;

    /**
     * 获取文档信息
     * @param index
     * @param id
     * @return 返回的是形如{"age":12,"name":"zhan"}的字符串
     * @throws IOException
     */
    String GetDoucumment(String index, String id) throws IOException;

    /**
     * 更新文档信息
     * @throws IOException
     */
    boolean UpdateDocument(Object object, String index, String id) throws IOException;

    /**
     * 删除文档信息
     * @throws IOException
     */
    boolean DeleteDocument(String index, String id) throws IOException;

    /**
     * 批量插入文档信息
     * @throws IOException
     */
    boolean addmoredocument(ArrayList<Object> list, String index, String id) throws IOException;

    /**
     * 精确查询 (例如有张三,张四,张五,要查询张三的话就只能得到一个结果即张三)
     * @param index
     * @param content 需要查询的名称
     * @param size 每一页需要获取多少条数据
     * @param from 从第几个数据开始
     * @return 返回SearchHit[]的数据中的每一个元素都是一个对象 形如{{name=张三, age=12},{name=张三, age=13}}
     */
    List<Map<String,Object>> termQuery(String index, TreeMap<String, Object> content, int size, int from, boolean ishigh) throws IOException;

    /**
     * 使用分词器解析进行查询 (假如要查询的是张三,则会使用ik分词器进行解析,分成张和三),代码结构与上面的基本一样
     * @param index
     * @param content key:属性 value:查询的信息
     * @param size
     * @param from
     * @return 返回的结果就不仅仅包含张三,也包含了姓张的用户的信息了
     */
    List<Map<String,Object>> matchQuery(String index, TreeMap<String, Object> content, int size, int from, boolean ishigh) throws IOException;

    /**
     * 多条件match查询 并且是查的是并集(形如where name = 'zhan' and age = 12)
     * @param index
     * @param content key:属性 value:查询的信息
     * @param size
     * @param from
     * @throws IOException
     */
    List<Map<String,Object>> boolmustQuery(String index, TreeMap<String, Object> content, int size, int from) throws IOException;
}


EsSearchServiceImpl.java

@Service
public class EsSearchServiceImpl implements EsSearchService {
    @Qualifier("restHighLevelClient")
    @Autowired
    private RestHighLevelClient client;


    @Override
    public boolean CreateIndex(String index) throws IOException {
        //1.创建索引请求
        CreateIndexRequest request = new CreateIndexRequest(index);
        //2.客户端执行请求IndicesClient,请求后获得相应
        CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);
        return response.isAcknowledged();
    }


    @Override
    public boolean isExit(String index) throws IOException {
        GetIndexRequest request = new GetIndexRequest(index);
        boolean exists = client.indices().exists(request,RequestOptions.DEFAULT);
        return exists;
    }


    @Override
    public boolean delete(String index) throws IOException {
        DeleteIndexRequest request = new DeleteIndexRequest(index);
        AcknowledgedResponse delete = client.indices().delete(request,RequestOptions.DEFAULT);
        return delete.isAcknowledged();
    }


    @Override
    public boolean addDocument(String index, String id, Object object) throws IOException {
        IndexRequest request = new IndexRequest(index);
        //规则 一般的文档形如 put /index/_doc/1
        request.id(id);//如果不设置id的话会自动分配id
        request.timeout("1s");//设置超时时间
        //将我们的数据放入请求Json中
        request.source(JSON.toJSONString(object), XContentType.JSON);
        //客户端发送请求,获取相应的结果
        IndexResponse response = client.index(request,RequestOptions.DEFAULT);
        return response.getShardInfo().getSuccessful()>0?true:false;
    }


    @Override
    public boolean isdocuexit(String index, String id) throws IOException {
        GetRequest getRequest = new GetRequest(index,id);
        //不获取返回的_source上下文
        getRequest.fetchSourceContext(new FetchSourceContext(false));
        getRequest.storedFields("_none_");
        return client.exists(getRequest,RequestOptions.DEFAULT);
    }


    @Override
    public String GetDoucumment(String index, String id) throws IOException {
        GetRequest getRequest = new GetRequest(index, id);
        GetResponse response = client.get(getRequest, RequestOptions.DEFAULT);
        return response.getSourceAsString();
    }


    @Override
    public boolean UpdateDocument(Object object, String index, String id) throws IOException {
        UpdateRequest request = new UpdateRequest(index, id);
        request.timeout("1s");

        request.doc(JSON.toJSONString(object),XContentType.JSON);
        UpdateResponse update = client.update(request, RequestOptions.DEFAULT);
        return update.getShardInfo().getSuccessful()>0?true:false;
    }


    @Override
    public boolean DeleteDocument(String index, String id) throws IOException{
        DeleteRequest request = new DeleteRequest(index,id);
        request.timeout("1s");
        DeleteResponse deleteResponse = client.delete(request,RequestOptions.DEFAULT);
        return deleteResponse.getShardInfo().getSuccessful()>0?true:false;
    }


    @Override
    public boolean addmoredocument(ArrayList<Object> list, String index, String id) throws IOException{
        BulkRequest bulkRequest = new BulkRequest();
        bulkRequest.timeout("1s");
        //批量处理请求
        for (int i=0;i<list.size();i++){
            bulkRequest.add(
                    new IndexRequest(index)
                            .id(id)
                            .source(JSON.toJSONString(list.get(i)),XContentType.JSON));
        }
        BulkResponse responses = client.bulk(bulkRequest,RequestOptions.DEFAULT);
        //是否失败 false-没有失败
        return responses.hasFailures()?false:true;
    }


    @Override
    public List<Map<String,Object>> termQuery(String index, TreeMap<String, Object> content, int size, int from, boolean ishigh) throws IOException {
        SearchRequest searchRequest = new SearchRequest(index);
        //构建查询条件
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        System.out.println(content.firstKey());
        //查询条件
        TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery(content.firstKey(),content.get(content.firstKey()));
        sourceBuilder.query(termQueryBuilder);
        sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
        //获取多少条数据
        sourceBuilder.size(size);
        //从第几行开始
        sourceBuilder.from(from);
        //是否要将查询的结果中将搜索的关键词高亮
        if (ishigh){
            HighlightBuilder highlightBuilder = new HighlightBuilder();
            //设置高亮的属性
            highlightBuilder.field(content.firstKey());
            //也可以自定义高亮的样式,这里我使用的是默认的方式
            sourceBuilder.highlighter(highlightBuilder);
        }
        //将查询条件放入需要查询中
        searchRequest.source(sourceBuilder);

        //获取相应的数据
        SearchResponse searchResponse = client.search(searchRequest,RequestOptions.DEFAULT);
        SearchHit[] hits = searchResponse.getHits().getHits();

        ArrayList<Map<String,Object>> result = new ArrayList<>();
        for (SearchHit searchHit:hits){
            Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
            //获取高亮的信息
            HighlightField property = highlightFields.get(content.firstKey());
            //查询的元素数据(没有高亮)
            Map<String, Object> sourceAsMap = searchHit.getSourceAsMap();
            if (ishigh){
                if (property!=null){
                    Text[] fragments = property.fragments();
                    String n_title = "";
                    for (Text text:fragments){
                        n_title += text;
                    }
                    sourceAsMap.put(content.firstKey(),n_title);
                }
            }
            result.add(sourceAsMap);
        }
        return result;
    }


    @Override
    public List<Map<String,Object>> matchQuery(String index, TreeMap<String, Object> content, int size, int from, boolean ishigh) throws IOException {
        SearchRequest searchRequest = new SearchRequest(index);
        //构建查询条件
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //查询条件
        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery(content.firstKey(),content.get(content.firstKey()));
        sourceBuilder.query(matchQueryBuilder);
        sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
        //获取多少条数据
        sourceBuilder.size(size);
        //从第几行开始
        sourceBuilder.from(from);
        //是否要高亮
        if (ishigh){
            HighlightBuilder highlightBuilder = new HighlightBuilder();
            //设置高亮的属性
            highlightBuilder.field(content.firstKey());
            //也可以自定义高亮的样式,这里我使用的是默认的方式
            sourceBuilder.highlighter(highlightBuilder);
        }
        //将查询条件放入需要查询中
        searchRequest.source(sourceBuilder);

        //获取相应的数据
        SearchResponse searchResponse = client.search(searchRequest,RequestOptions.DEFAULT);
        SearchHit[] hits = searchResponse.getHits().getHits();

        ArrayList<Map<String,Object>> result = new ArrayList<>();
        for (SearchHit searchHit:hits){
            Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
            //获取高亮的信息
            HighlightField property = highlightFields.get(content.firstKey());
            //查询的元素数据(没有高亮)
            Map<String, Object> sourceAsMap = searchHit.getSourceAsMap();
            if (ishigh){
                if (property!=null){
                    Text[] fragments = property.fragments();
                    String n_title = "";
                    for (Text text:fragments){
                        n_title += text;
                    }
                    sourceAsMap.put(content.firstKey(),n_title);
                }
            }
            result.add(sourceAsMap);
        }
        return result;
    }



    @Override
    public List<Map<String,Object>> boolmustQuery(String index, TreeMap<String, Object> content, int size, int from) throws IOException {
        SearchRequest searchRequest = new SearchRequest(index);
        //构建查询条件
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //查询条件
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        Set keys = content.keySet();
        for (Object key:keys){
            //将要查询的条件加入
            boolQueryBuilder.must(QueryBuilders.termQuery((String) key,content.get(key)));
        }
        sourceBuilder.query(boolQueryBuilder);
        sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
        //获取多少条数据
        sourceBuilder.size(size);
        //从第几行开始
        sourceBuilder.from(from);

        //将查询条件放入需要查询中
        searchRequest.source(sourceBuilder);

        //获取相应的数据
        SearchResponse searchResponse = client.search(searchRequest,RequestOptions.DEFAULT);
        SearchHit[] hits = searchResponse.getHits().getHits();

        ArrayList<Map<String,Object>> result = new ArrayList<>();

        for (SearchHit searchHit:hits){
            Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
            result.add(searchHit.getSourceAsMap());
        }
        return result;
    }

}

注:不需要中文分词的字段设置成@Field(type = FieldType.Keyword)类型,需要中文分词的设置成@Field(analyzer = “ik_max_word”,type = FieldType.Text)类型。
类似下面这样的

public class User {
    @Field(type = FieldType.Keyword)
    private String name;
    
    private int age;
    
    @Field(analyzer = "ik_max_word",type = FieldType.Text)
    private String desc;

    //省略了所有getter和setter方法
}

猜你喜欢

转载自blog.csdn.net/weixin_43517302/article/details/105756875