springboot使用elasticsearch的客户端操作eslaticsearch
阅读原文时间:2023年07月09日阅读:1

一  ES客户端

  ES提供多种不同的客户端:

    1、TransportClient

    ES提供的传统客户端,官方计划8.0版本删除此客户端。

    2、RestClient

    RestClient是官方推荐使用的,它包括两种:Java Low Level REST Client和 Java High Level REST Client。

    ES在6.0之后提供 Java High Level REST Client, 两种客户端官方更推荐使用 Java High Level REST Client,不过当前它还处于完善中,有些功能还没有。

    3 spring-data-elasticsearch

    这个是基于TransportClient开发的,虽然在有些版本还是可以用,但是更新对应版本太慢了

采用 Java High Level REST Client,如果它有不支持的功能,则使用Java Low Level REST Client。

二 整合

  首先是pom.xml

  注意我这个地方引入的是springbooot2.0.1   版本,首先这么做下去,再升级


http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.
org.springframework.boot spring-boot-starter-parent 2.0..RELEASE
com.cxy
elasticsearch
0.0.-SNAPSHOT
elasticsearch
Demo project for Spring Boot

<properties>  
    <java.version>1.8</java.version>  
</properties>

<dependencies>  
    <dependency>  
        <groupId>org.springframework.boot</groupId>  
        <artifactId>spring-boot-starter-web</artifactId>  
    </dependency>  
    <dependency>  
        <groupId>org.elasticsearch.client</groupId>  
        <artifactId>elasticsearch-rest-high-level-client</artifactId>  
        <version>6.2.</version>  
    </dependency>  
    <dependency>  
        <groupId>org.elasticsearch</groupId>  
        <artifactId>elasticsearch</artifactId>  
        <version>6.2.</version>  
    </dependency>  
    <dependency>  
        <groupId>org.springframework.boot</groupId>  
        <artifactId>spring-boot-starter-test</artifactId>  
        <scope>test</scope>  
    </dependency>  
    <dependency>  
        <groupId>com.alibaba</groupId>  
        <artifactId>fastjson</artifactId>  
    </dependency>  
    <dependency>  
        <groupId>org.apache.commons</groupId>  
        <artifactId>commons-io</artifactId>  
    </dependency>  
    <dependency>  
        <groupId>org.apache.commons</groupId>  
        <artifactId>commons-lang3</artifactId>  
    </dependency>  
    <dependency>  
        <groupId>org.springframework.boot</groupId>  
        <artifactId>spring-boot-starter-test</artifactId>  
        <scope>test</scope>  
    </dependency>  
</dependencies>

<build>  
    <plugins>  
        <plugin>  
            <groupId>org.springframework.boot</groupId>  
            <artifactId>spring-boot-maven-plugin</artifactId>  
        </plugin>  
    </plugins>  
</build>

yml文件:

server:
port: ${port:}
spring:
application:
name:search-service
elasticsearch:
hostlist: ${eshostlist:127.0.0.1:}

es的配置类:

package com.cxy.elasticsearch.config;

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

@Configuration
public class ElasticsearchConfig {

@Value("${spring.elasticsearch.hostlist}")  
private String hostlist;

@Bean  
public RestHighLevelClient restHighLevelClient(){  
    //解析hostlist配置信息  
    String\[\] split = hostlist.split(",");  
    //创建HttpHost数组,其中存放es主机和端口的配置信息  
    HttpHost\[\] httpHostArray = new HttpHost\[split.length\];  
    for(int i=;i<split.length;i++){  
        String item = split\[i\];  
        httpHostArray\[i\] = new HttpHost(item.split(":")\[\], Integer.parseInt(item.split(":")\[\]), "http");  
    }  
    //创建RestHighLevelClient客户端  
    return new RestHighLevelClient(RestClient.builder(httpHostArray));  
}

//项目主要使用RestHighLevelClient,对于低级的客户端暂时不用  
@Bean  
public RestClient restClient(){  
    //解析hostlist配置信息  
    String\[\] split = hostlist.split(",");  
    //创建HttpHost数组,其中存放es主机和端口的配置信息  
    HttpHost\[\] httpHostArray = new HttpHost\[split.length\];  
    for(int i=;i<split.length;i++){  
        String item = split\[i\];  
        httpHostArray\[i\] = new HttpHost(item.split(":")\[\], Integer.parseInt(item.split(":")\[\]), "http");  
    }  
    return RestClient.builder(httpHostArray).build();  
}

}

然后再看我的controller

package com.cxy.elasticsearch.controller;

import org.elasticsearch.action.DocWriteResponse;
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.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.IndicesClient;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@RestController
public class EsController {
@Autowired
RestHighLevelClient client;

@Autowired  
RestClient restClient;  
@RequestMapping(value = "/createIndex" ,method = RequestMethod.POST)  
public String createIndex(){  
    //创建索引请求对象  
    CreateIndexRequest createIndexRequest = new CreateIndexRequest("chenxuyou3");  
    // 设置参数  
    createIndexRequest.settings(Settings.builder().put("number\_of\_shards","").put("number\_of\_replicas",""));  
    //指定映射  
    createIndexRequest.mapping("doc"," {\\n" +  
            " \\t\\"properties\\": {\\n" +  
            "            \\"studymodel\\":{\\n" +  
            "             \\"type\\":\\"keyword\\"\\n" +  
            "           },\\n" +  
            "            \\"name\\":{\\n" +  
            "             \\"type\\":\\"keyword\\"\\n" +  
            "           },\\n" +  
            "           \\"description\\": {\\n" +  
            "              \\"type\\": \\"text\\",\\n" +  
            "              \\"analyzer\\":\\"ik\_max\_word\\",\\n" +  
            "              \\"search\_analyzer\\":\\"ik\_smart\\"\\n" +  
            "           },\\n" +  
            "           \\"pic\\":{\\n" +  
            "             \\"type\\":\\"text\\",\\n" +  
            "             \\"index\\":false\\n" +  
            "           }\\n" +  
            " \\t}\\n" +  
            "}", XContentType.JSON);  
    //指定索引操作的客户端  
    IndicesClient indices = client.indices();  
    //执行创建索引库  
    CreateIndexResponse createIndexResponse = null;  
    try {  
        createIndexResponse = indices.create(createIndexRequest);  
    } catch (IOException e) {  
        e.printStackTrace();  
    }  
    boolean acknowledged = createIndexResponse.isAcknowledged();  
    //获取返回结果  
    System.err.println(acknowledged);  
    return "ok";  
}  
@RequestMapping(value = "/deleteIndex",method = RequestMethod.POST)  
public String deleteIndex(){  
    DeleteIndexRequest chenxuyou3 = new DeleteIndexRequest("chenxuyou2");  
    IndicesClient indices = client.indices();  
    AcknowledgedResponse delete =null;  
    try {  
        delete = indices.delete(chenxuyou3);  
    } catch (IOException e) {  
        e.printStackTrace();  
    }  
    boolean acknowledged = delete.isAcknowledged();  
    System.err.println(acknowledged);  
    return "";  
}  
@RequestMapping(value = "/addDoc",method = RequestMethod.POST)  
public String addDoc(){  

//文档内容
//准备json数据
Map jsonMap = new HashMap<>();
jsonMap.put("name", "spring cloud实战");
jsonMap.put("description", "本课程主要从四个章节进行讲解: 1.微服务架构入门 2.spring cloud 基础入门 3.实战Spring Boot 4.注册中心eureka。");
jsonMap.put("studymodel", "");
SimpleDateFormat dateFormat =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
jsonMap.put("timestamp", dateFormat.format(new Date()));
jsonMap.put("price", 5.6f);

    //创建索引创建对象  
    //带有type的方法已经废弃  
   // IndexRequest indexRequest = new IndexRequest("chenxuyou3","doc");  
    IndexRequest indexRequest = new IndexRequest("chenxuyou3");  
    //文档内容  
    indexRequest.source(jsonMap);  
    //通过client进行http的请求  
    IndexResponse indexResponse = null;  
    try {  
        indexResponse = client.index(indexRequest);  
    } catch (IOException e) {  
        e.printStackTrace();  
    }  
    DocWriteResponse.Result result = indexResponse.getResult();  
    System.err.println(result);  
    return "ok";  
}  
@RequestMapping(value = "/selectDoc",method = RequestMethod.GET)  
public String selectDoc(){  
    //查询请求对象  
   // GetRequest getRequest = new GetRequest("chenxuyou2","doc","8tyV-m4B7rvW\_ZY4LvVU");  
    GetRequest getRequest = new GetRequest("chenxuyou3","doc","8tyV-m4B7rvW\_ZY4LvVU");  
    GetResponse getResponse = null;  
    try {  
        getResponse = client.get(getRequest);  
    } catch (IOException e) {  
        e.printStackTrace();  
    }  
    //得到文档的内容  
    Map<String, Object> sourceAsMap = getResponse.getSourceAsMap();  
    System.out.println(sourceAsMap);  
    return "ok" ;  
}

}

然后启动项目可以看到很清晰的运行

调用 localhost:8085/createIndex

可以看到成功了,后面的也就自然可以操作了。

三  问题一:

修改springboot的版本为2.1.8,环境:我使用的es版本是6.2.1 版本:

出现问题:

{
"timestamp": "2019-12-15T04:46:53.518+0000",
"status": ,
"error": "Internal Server Error",
"message": "org.elasticsearch.client.Request.(Ljava/lang/String;Ljava/lang/String;)V",
"path": "/createIndex"
}

控制台:

java.lang.NoSuchMethodError: org.elasticsearch.client.Request.(Ljava/lang/String;Ljava/lang/String;)V
at org.elasticsearch.client.RestClient.performRequest(RestClient.java:) ~[elasticsearch-rest-client-6.4..jar:6.2.]
at org.elasticsearch.client.RestHighLevelClient.performRequest(RestHighLevelClient.java:) ~[elasticsearch-rest-high-level-client-6.2..jar:6.2.]
at org.elasticsearch.client.RestHighLevelClient.performRequestAndParseEntity(RestHighLevelClient.java:) ~[elasticsearch-rest-high-level-client-6.2..jar:6.2.]
at org.elasticsearch.client.IndicesClient.create(IndicesClient.java:) ~[elasticsearch-rest-high-level-client-6.2..jar:6.2.]
at com.cxy.elasticsearch.controller.EsController.createIndex(EsController.java:) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_191]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:) ~[na:1.8.0_191]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:) ~[na:1.8.0_191]
at java.lang.reflect.Method.invoke(Method.java:) ~[na:1.8.0_191]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:) ~[spring-web-5.1..RELEASE.jar:5.1..RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:) ~[spring-web-5.1..RELEASE.jar:5.1..RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:) ~[spring-webmvc-5.1..RELEASE.jar:5.1..RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:) ~[spring-webmvc-5.1..RELEASE.jar:5.1..RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:) ~[spring-webmvc-5.1..RELEASE.jar:5.1..RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:) ~[spring-webmvc-5.1..RELEASE.jar:5.1..RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:) ~[spring-webmvc-5.1..RELEASE.jar:5.1..RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:) ~[spring-webmvc-5.1..RELEASE.jar:5.1..RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:) ~[spring-webmvc-5.1..RELEASE.jar:5.1..RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:) ~[spring-webmvc-5.1..RELEASE.jar:5.1..RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:) ~[tomcat-embed-core-9.0..jar:9.0.]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:) ~[spring-webmvc-5.1..RELEASE.jar:5.1..RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:) ~[tomcat-embed-core-9.0..jar:9.0.]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:) ~[tomcat-embed-core-9.0..jar:9.0.]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:) ~[tomcat-embed-core-9.0..jar:9.0.]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:) ~[tomcat-embed-websocket-9.0..jar:9.0.]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:) ~[tomcat-embed-core-9.0..jar:9.0.]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:) ~[tomcat-embed-core-9.0..jar:9.0.]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:) ~[spring-web-5.1..RELEASE.jar:5.1..RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:) ~[spring-web-5.1..RELEASE.jar:5.1..RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:) ~[tomcat-embed-core-9.0..jar:9.0.]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:) ~[tomcat-embed-core-9.0..jar:9.0.]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:) ~[spring-web-5.1..RELEASE.jar:5.1..RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:) ~[spring-web-5.1..RELEASE.jar:5.1..RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:) ~[tomcat-embed-core-9.0..jar:9.0.]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:) ~[tomcat-embed-core-9.0..jar:9.0.]
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:) ~[spring-web-5.1..RELEASE.jar:5.1..RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:) ~[spring-web-5.1..RELEASE.jar:5.1..RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:) ~[tomcat-embed-core-9.0..jar:9.0.]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:) ~[tomcat-embed-core-9.0..jar:9.0.]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:) ~[spring-web-5.1..RELEASE.jar:5.1..RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:) ~[spring-web-5.1..RELEASE.jar:5.1..RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:) ~[tomcat-embed-core-9.0..jar:9.0.]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:) ~[tomcat-embed-core-9.0..jar:9.0.]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:) ~[tomcat-embed-core-9.0..jar:9.0.]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:) [tomcat-embed-core-9.0..jar:9.0.]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:) [tomcat-embed-core-9.0..jar:9.0.]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:) [tomcat-embed-core-9.0..jar:9.0.]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:) [tomcat-embed-core-9.0..jar:9.0.]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:) [tomcat-embed-core-9.0..jar:9.0.]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:) [tomcat-embed-core-9.0..jar:9.0.]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:) [tomcat-embed-core-9.0..jar:9.0.]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:) [tomcat-embed-core-9.0..jar:9.0.]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:) [tomcat-embed-core-9.0..jar:9.0.]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:) [tomcat-embed-core-9.0..jar:9.0.]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:) [tomcat-embed-core-9.0..jar:9.0.]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:) [na:1.8.0_191]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:) [na:1.8.0_191]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:) [tomcat-embed-core-9.0..jar:9.0.]
at java.lang.Thread.run(Thread.java:) [na:1.8.0_191]

java.lang.NoSuchMethodError: org.elasticsearch.client.Request.(Ljava/lang/String;Ljava/lang/String;)V

这句话的具体意思是这样的,就是没有这个方法,Request对象init的时候创建使用(String,String)后面v是值得意思

可以很清楚,就是升级时候,这个方法没了

/\*\* @deprecated \*/  
@Deprecated  
public Response performRequest(String method, String endpoint, Map<String, String> params, Header... headers) throws IOException {  
    Request request = new Request(method, endpoint);  
    addParameters(request, params);  
    addHeaders(request, headers);  
    return this.performRequest(request);  
}

由于这个方法已经废弃了,所以在重新去找的时候,版本升级,springboot就没有去找这个类,

所以就报错了

四 问题二

出现了上叙问题之后,我想到了解决方法,就是将client得版本升级为最新得,7.23

然后还有就是他那个type得移除,构造方法里面不能有type

最终由于跟我es版本不一致,

Search problem, contains unrecognized parameter: [typed_keys]

报包含错误得字段,我在删除得时候明没什么都没有

然后将版本进行升级:升级到6.6.1就成功了