赞
踩
首先有三种方式可以实现在java代码里操作ES,分别是Java API(TransportClient客户端),REST Client以及Data-ES,对于第一种,ES官方表示将在ES 8.0版本弃用,所以不是我们学习的重点。至于Data-ES,虽然它和SpringBoot集成的很好,容易上手,而且提供了很方便的api,但是据说不支持ES的权限数据,如果只是很简单的获取普通数据,Data-ES将是很好的一个方式。但如果需要获取权限数据呢?
首先pom依赖如下
- <dependencies>
- <!-- springboot相关 -->
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-test</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
- </dependency>
- <!--yml文件进行配置需要用到的依赖-->
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-configuration-processor</artifactId>
- <optional>true</optional>
- </dependency>
- <!-- elasticsearch -->
- <dependency>
- <groupId>org.elasticsearch</groupId>
- <artifactId>elasticsearch</artifactId>
- <version>6.8.4</version>
- </dependency>
- <dependency>
- <groupId>org.elasticsearch.client</groupId>
- <artifactId>elasticsearch-rest-client</artifactId>
- <version>6.8.4</version>
- </dependency>
- <dependency>
- <groupId>org.elasticsearch.plugin</groupId>
- <artifactId>reindex-client</artifactId>
- <version>6.8.4</version>
- </dependency>
- <!-- 工具包 -->
- <dependency>
- <groupId>com.alibaba</groupId>
- <artifactId>fastjson</artifactId>
- <version>1.2.54</version>
- </dependency>
- <dependency>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-lang3</artifactId>
- </dependency>
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- <optional>true</optional>
- </dependency>
- <!-- swagger -->
- <dependency>
- <groupId>io.springfox</groupId>
- <artifactId>springfox-swagger2</artifactId>
- <version>2.7.0</version>
- </dependency>
- <dependency>
- <groupId>io.springfox</groupId>
- <artifactId>springfox-swagger-ui</artifactId>
- <version>2.7.0</version>
- </dependency>
- <dependency>
- <groupId>io.springfox</groupId>
- <artifactId>springfox-staticdocs</artifactId>
- <version>2.4.0</version>
- </dependency>
- <dependency>
- <groupId>io.github.robwin</groupId>
- <artifactId>assertj-swagger</artifactId>
- <version>0.2.0</version>
- <scope>test</scope>
- </dependency>
-
- </dependencies>
然后是yml文件
- server:
- port: 8080
-
- swagger:
- enable: true
- title: ElasticSearch-demo
- description:
- serviceUrl: http://localhost:8080/
- version: 1.0.0
- controllers: com.example.es.controller
-
- elasticsearch:
- user:
- password:
- host: 192.168.145.128
- port: 9200
PS:swagger和lombok是好东西
配置类:
- @Configuration
- @Slf4j
- public class ESConfig {
-
- @Value("${elasticsearch.user}")
- private String userName;
- @Value("${elasticsearch.password}")
- private String password;
- @Value("${elasticsearch.host}")
- private String host;
- @Value("${elasticsearch.port}")
- private Integer port;
-
- @Bean(name = "myClient")
- public RestClient getRestClient() {
- //基本的连接
- RestClientBuilder clientBuilder = RestClient.builder(new HttpHost(host, port));
- //配置身份验证
- final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
- credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(userName, password));
- clientBuilder.setHttpClientConfigCallback(
- httpClientBuilder -> httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider));
- //设置连接超时和套接字超时
- clientBuilder.setRequestConfigCallback(builder -> builder.setConnectTimeout(10000).setSocketTimeout(60000));
- //设置节点选择器
- clientBuilder.setNodeSelector(NodeSelector.SKIP_DEDICATED_MASTERS);
- //配置HTTP异步请求ES的线程数
- clientBuilder.setHttpClientConfigCallback(
- httpAsyncClientBuilder -> httpAsyncClientBuilder.setDefaultIOReactorConfig(
- IOReactorConfig.custom().setIoThreadCount(1).build()));
- //设置监听器,每次节点失败都可以监听到,可以作额外处理
- clientBuilder.setFailureListener(new RestClient.FailureListener() {
- @Override
- public void onFailure(Node node) {
- super.onFailure(node);
- log.error(node.getHost() + "--->该节点失败了");
- }
- });
-
- return clientBuilder.build();
- }
-
-
- }
这样的话,已经算是集成到springboot了,但是如何实现增删改查?
首先引入两个bean,后续的代码有用
Person类,这个是我们接下来要操作的实体类
- @Data
- public class Person {
-
- private String id;
- private String name;
- private String birthday;
- private String addr;
-
- }
SearchParam类,用于拼接请求内容,包括index,type和id
- @Data
- public class SearchParam {
-
- @ApiModelProperty("索引")
- private String index;
- @ApiModelProperty("类型")
- private String type;
- @ApiModelProperty("id")
- private String id;
-
- }
接下来是Controller层的代码
- @RestController
- @RequestMapping("/es")
- public class MyController {
-
- @Autowired
- private MyService service;
-
- @PostMapping("/search")
- @ApiOperation("根据id查询ES对应的数据")
- public JSONObject getDataById(@RequestBody SearchParam param) {
- return service.getDataById(param);
- }
-
- @PostMapping("/add")
- @ApiOperation("往ES里插入数据")
- public ResponseEntity add(@RequestBody SearchParam param) {
- return service.add(param);
- }
-
- @PostMapping("/update")
- @ApiOperation("根据id更新文档内容")
- public ResponseEntity update(@RequestBody SearchParam param) {
- return service.update(param);
- }
-
- @PostMapping("/delete")
- @ApiOperation("根据id更新文档内容")
- public ResponseEntity delete(@RequestBody SearchParam param) {
- return service.delete(param);
- }
-
-
- }
重点来了,Service层,具体实现方法
在service类里,我们需要用到我们之前在config配置类里配置的bean,但是如果直接注入的话,spring会报如下错误
意思是spring不知道我们现在用哪个类,对于这个报错,我们做如下处理
- @Service
- @Slf4j
- public class MyService {
-
- @Qualifier("myClient")
- @Autowired
- private RestClient client;
-
- }
用@Qualifier注解来指定具体要注入哪个bean
通过id查询:
- /**
- * 根据id查询文档内容
- *
- * @param param
- * @return
- */
- public JSONObject getDataById(SearchParam param) {
- //拼接查询内容
- String body = param.getIndex() + "/" + param.getType() + "/" + param.getId();
- Request request = new Request("GET", body);
- JSONObject jsonObject = new JSONObject();
- try {
- Response response = client.performRequest(request);
- String responseBody = EntityUtils.toString(response.getEntity(), "UTF-8");
- JSONObject json = JSONObject.parseObject(responseBody);
- //获取我们需要的内容
- Object source = json.get("_source");
- jsonObject = JSONObject.parseObject(source.toString());
- } catch (IOException e) {
- log.error(e.getMessage());
- }
- return jsonObject;
- }
添加文档:
- /**
- * 添加文档
- *
- * @param param
- * @return
- */
- public ResponseEntity add(SearchParam param) {
- Person person = new Person();
- person.setName("朱元璋");
- person.setAddr("安徽凤阳");
- person.setBirthday("1328-10-29");
- person.setId("1234567890");
- //以bean的id为该文档的id,以便查询
- String body = param.getIndex() + "/" + param.getType() + "/" + person.getId();
- String responseBody = "";
- try {
- Request request = new Request("POST", body);
- JSONObject jsonObject = (JSONObject) JSONObject.toJSON(person);
- //设置请求体并指定ContentType和编码格式
- request.setEntity(new NStringEntity(jsonObject.toString(), "UTF-8"));
- Response response = client.performRequest(request);
- //获取响应体
- responseBody = EntityUtils.toString(response.getEntity());
- } catch (IOException e) {
- log.error(e.getMessage());
- }
- return new ResponseEntity<>(responseBody, HttpStatus.OK);
- }
根据id更新文档内容:
- /**
- * 根据id更新文档内容
- *
- * @param param
- * @return
- */
- public ResponseEntity update(SearchParam param) {
- Person person = new Person();
- person.setName("朱棣");
- person.setAddr("南京");
- person.setBirthday("1360-05-02");
- //需要更新对应的id
- String body = param.getIndex() + "/" + param.getType() + "/" + param.getId() + "/_update";
- String responseBody = "";
- try {
- //构造http请求
- Request request = new Request("POST", body);
- JSONObject json = (JSONObject) JSONObject.toJSON(person);
- JSONObject jsonObject = new JSONObject();
- //将数据由"doc"包住,以便内部识别
- jsonObject.put("doc", json);
- request.setEntity(new NStringEntity(jsonObject.toString(), "UTF-8"));
- Response response = client.performRequest(request);
- //获取响应体
- responseBody = EntityUtils.toString(response.getEntity());
- } catch (Exception e) {
- log.error(e.getMessage());
- }
- return new ResponseEntity<>(responseBody, HttpStatus.OK);
- }
根据id删除对应文档:
- /**
- * 根据id删除文档
- *
- * @param param
- * @return
- */
- public ResponseEntity delete(SearchParam param) {
- String body = param.getIndex() + "/" + param.getType() + "/" + param.getId();
- String responseBody = "";
- try {
- Request request = new Request("DELETE", body);
- // 执行HTTP请求
- Response response = client.performRequest(request);
- // 获取结果
- responseBody = EntityUtils.toString(response.getEntity());
- } catch (IOException e) {
- log.error(e.getMessage());
- }
- return new ResponseEntity<>(responseBody, HttpStatus.OK);
- }
好了,简单的增删改查已经可以实现了,而且对于增删改这三种操作来说,以上的方法已经基本够用了,但是对于查询的操作,远远不够,比如我不知道文档的id,我需要通过name="张三"这个条件查询出所有符合条件的文档内容来,还有我需要知道出生日期在1990-1991年之间的,如此种种,上述方法不可能实现。
关于复杂查询的,SpringBoot工程整合ElasticSearch(通过Rest-High-Level-Client)并实现较复杂的查询
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。