文章目录

  • 概述
  • 官方JAVA API文档
  • 工程
    • pom.xml
    • es配置文件
    • Es配置类
    • 控制层
      • 简单查询
      • 新增数据
      • 删除数据
      • 更新数据
      • 复合查询
  • 其他
    • 新建索引
    • 删除索引
    • 判断index中某个type是否存在
  • spring-data-elasticsearch 操作ES
  • 代码

概述

前面几篇,学习了ES的基本操作,那我们这里集成到代码中吧。 我们这里没有使用Spring 提供的 spring-boot-starter-data-elasticsearch,使用的是ES原生的API 。


官方JAVA API文档

当前7.0
https://www.elastic.co/guide/en/elasticsearch/client/java-api/current/index.html

5.6

https://www.elastic.co/guide/en/elasticsearch/client/java-api/5.6/index.html

工程

ES服务端的版本 5.6.16 ,工程里es客户端的版本最好和服务端保持一致 。 正好Spring Boot 2.0.9RELEASE版本搭配transport里es是5.6.16版本。


pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0.9.RELEASE</version><relativePath /> <!-- lookup parent from repository --></parent><groupId>masterSpringMvc</groupId><artifactId>springBootElasticSearch</artifactId><version>0.0.1-SNAPSHOT</version><name>springBootElasticSearch</name><description>masterSpringMvc project for Spring Boot</description><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>transport</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>


es配置文件

# Elasticsearch
elasticsearch.ip=127.0.0.1
#9200端口是RESTFul API来访问ElasticSearch的端口,9300端口是es节点通讯的默认端口,给java程序用的配置9300elasticsearch.port=9300
elasticsearch.pool=5# 集群的名字,和elasticsearch.yml中的cluster.name保持一致elasticsearch.cluster.name=artisan

Es配置类

package com.artisan.config;import java.net.InetAddress;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class ESConfig {private static final Logger logger = LoggerFactory.getLogger(ESConfig.class);@Value("${elasticsearch.ip}")private String hostName;@Value("${elasticsearch.port}")private String port;@Value("${elasticsearch.cluster.name}")private String clusterName;@Value("${elasticsearch.pool}")private String poolSize;@Beanpublic TransportClient transportClient()  {logger.info("Elasticsearch begin to init ");TransportClient transportClient = null;try {// 地址信息InetSocketTransportAddress transportAddress = new InetSocketTransportAddress(InetAddress.getByName(hostName), Integer.valueOf(port));// 配置信息Settings esSetting = Settings.builder().put("cluster.name", clusterName) // 集群名字.put("client.transport.sniff", true)// 增加嗅探机制,找到ES集群.put("thread_pool.search.size", Integer.parseInt(poolSize))// 线程池个数.build();// 配置信息Settings自定义transportClient = new PreBuiltTransportClient(esSetting);transportClient.addTransportAddresses(transportAddress);} catch (Exception e) {logger.error("TransportClient create error", e);}return transportClient;}
}

控制层

简单起见,我们直接在Controller层操作ES吧,仅仅是为了测试下功能。

简单查询

先写个简单的根据id获取数据的方法来测试下班

package com.artisan.controller;import java.util.Map;import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;@RestController
public class ESController {@Autowiredprivate TransportClient client;@GetMapping("/book/novel/{id}")public ResponseEntity<Map<String, Object>> getByIdFromES(@PathVariable String id){GetResponse response = this.client.prepareGet("book", "novel", id).get();if (!response.isExists()) {return new ResponseEntity<>(HttpStatus.NOT_FOUND);}return new ResponseEntity<Map<String, Object>>(response.getSource(),HttpStatus.OK);}}

启动下服务,在浏览器或者postman中访问下吧

我们通过head插件来看下id=11的数据

OK,可以访问到正确的数据。


新增数据

ESController新增add方法

@PostMapping("/book/novel/add")public ResponseEntity<String> add(NovelDTO novel) {try {XContentBuilder builder = XContentFactory.jsonBuilder().startObject().field("title", novel.getTitle()).field("author", novel.getAuthor()).field("word_count", novel.getWordCount()).field("public_date", novel.getPublishDate().getTime()).endObject();IndexResponse response = this.client.prepareIndex("book", "novel").setSource(builder).get();return new ResponseEntity<String>(response.getId(), HttpStatus.OK);} catch (IOException e) {e.printStackTrace();return new ResponseEntity<String>(HttpStatus.INTERNAL_SERVER_ERROR);}}

我们把数据请求参数封装到了NovelDTO 中

package com.artisan.dto;import java.util.Date;import org.springframework.format.annotation.DateTimeFormat;public class NovelDTO {private String title;private String author;private String wordCount;@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")private Date publishDate;// set/get方法 省略
}

启动服务,POST http://localhost:8080/book/novel/add

head插件中查看数据 访问 http://localhost:9100/


新增成功



如果要想用JSON传的话,需要在方法入参前加入 @RequestBody ,postman中更改如下

public ResponseEntity<String> add(@RequestBody  NovelDTO novel) {}

删除数据

@DeleteMapping("/book/novel/del")public ResponseEntity<String> delete(String id ){DeleteResponse response = this.client.prepareDelete("book", "novel", id).get();return new ResponseEntity<String>(response.getResult().toString(),HttpStatus.OK);}

把刚才新增的数据删掉

通过head插件查看已经没有该记录了,删除OK


更新数据

举个例子,根据id更新title

/*** 根据id 修改title* @param id* @param title* @return*/@PutMapping("/book/novel/update")public ResponseEntity<String> update(@RequestParam(name="id")String id ,@RequestParam(name="title")    String title){UpdateRequest updateRequest = new UpdateRequest("book", "novel", id);try {XContentBuilder builder = XContentFactory.jsonBuilder().startObject().field("title",title).endObject();updateRequest.doc(builder);UpdateResponse response = this.client.update(updateRequest).get();return new ResponseEntity<String>(response.getResult().toString(), HttpStatus.OK);} catch (Exception e) {e.printStackTrace();return new ResponseEntity<String>(HttpStatus.INTERNAL_SERVER_ERROR);} }

head插件查看


复合查询

 /*** 综合查询* @param title* @param author* @param gtWordCount* @param ltWordCount* @return*/@PostMapping("/book/novel/query")public ResponseEntity<List<Map<String, Object>>> query(@RequestParam(name="title",required=false)String title , @RequestParam(name="author",required=false)String author ,@RequestParam(name="gtWordCount",defaultValue="0") Integer gtWordCount ,@RequestParam(name="ltWordCount",required=false) Integer ltWordCount  ) {BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();if (title !=null) {boolQueryBuilder.must(QueryBuilders.matchQuery("title", title));}if (author !=null) {boolQueryBuilder.must(QueryBuilders.matchQuery("author", author));}RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("word_count").from(gtWordCount);if (ltWordCount != null && ltWordCount > 0) {rangeQueryBuilder.to(ltWordCount);}// 关联boolQueryBuilder.filter(rangeQueryBuilder);SearchRequestBuilder builder = this.client.prepareSearch("book").setTypes("novel").setSearchType(SearchType.DFS_QUERY_THEN_FETCH).setQuery(boolQueryBuilder).setFrom(0).setSize(10);System.out.println("请求JSON数据:\n" + builder);SearchResponse response = builder.get();List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();for(SearchHit searchHit : response.getHits()) {list.add(searchHit.getSource());}return new ResponseEntity<List<Map<String, Object>>>(list, HttpStatus.OK);}

看下控制台输出的

请求JSON数据:

{"from" : 0,"size" : 10,"query" : {"bool" : {"must" : [{"match" : {"title" : {"query" : "Elasticsearch","operator" : "OR","prefix_length" : 0,"max_expansions" : 50,"fuzzy_transpositions" : true,"lenient" : false,"zero_terms_query" : "NONE","boost" : 1.0}}}],"filter" : [{"range" : {"word_count" : {"from" : 500,"to" : null,"include_lower" : true,"include_upper" : true,"boost" : 1.0}}}],"disable_coord" : false,"adjust_pure_negative" : true,"boost" : 1.0}}
}

使用postman测试下 ,返回了3条数据,符合预期。


其他

上面通过代码实现了数据的CRUD操作,那么我们把多索引和type的操作也尝试写下吧

工具类

package com.artisan.utils;import javax.annotation.PostConstruct;import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse;
import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsRequest;
import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component
public class ESUtil {private static final Logger logger = LoggerFactory.getLogger(ESUtil.class);@Autowiredprivate TransportClient transportClient;private static TransportClient client;@PostConstructpublic void init() {client = this.transportClient;}/*** 创建索引** @param index* @return*/public static boolean createIndex(String index) {if (!isIndexExist(index)) {logger.info("Index is not exits!");CreateIndexResponse indexresponse = client.admin().indices().prepareCreate(index).execute().actionGet();logger.info("执行建立成功?" + indexresponse.isAcknowledged());return indexresponse.isAcknowledged();}return false;}/*** 删除索引** @param index* @return*/public static boolean deleteIndex(String index) {if (!isIndexExist(index)) {logger.info("Index is not exits!");}DeleteIndexResponse dResponse = client.admin().indices().prepareDelete(index).execute().actionGet();if (dResponse.isAcknowledged()) {logger.info("delete index " + index + "  successfully!");} else {logger.info("Fail to delete index " + index);}return dResponse.isAcknowledged();}/*** 判断索引是否存在** @param index* @return*/public static boolean isIndexExist(String index) {IndicesExistsResponse inExistsResponse = client.admin().indices().exists(new IndicesExistsRequest(index)).actionGet();if (inExistsResponse.isExists()) {logger.info("Index [" + index + "] is exist!");} else {logger.info("Index [" + index + "] is not exist!");}return inExistsResponse.isExists();}/*** 判断index下指定type是否存在* * @param index* @param type* @return*/public static boolean isTypeExist(String index, String type) {return isIndexExist(index)? client.admin().indices().prepareTypesExists(index).setTypes(type).execute().actionGet().isExists(): false;}}

新建索引

@SuppressWarnings({ "rawtypes", "unchecked" })@PostMapping("/index/create")public ResponseEntity create(String index){if (ESUtil.createIndex(index)) {return new ResponseEntity(Boolean.TRUE,HttpStatus.OK);}else {return new ResponseEntity(HttpStatus.FOUND);}}

测试

head查看下


删除索引

 @SuppressWarnings({ "rawtypes", "unchecked" })@PostMapping("/index/delete")public ResponseEntity deleteIndex(String index){if (ESUtil.deleteIndex(index)) {return new ResponseEntity(Boolean.TRUE,HttpStatus.OK);}else {return new ResponseEntity(HttpStatus.NOT_FOUND);}}

测试下

head查看,已经删除成功


判断index中某个type是否存在

 @SuppressWarnings({ "rawtypes", "unchecked" })@PostMapping("/index/isTypeExist")public ResponseEntity isTypeExist(String index,String type){if (ESUtil.isTypeExist(index,type)) {return new ResponseEntity(Boolean.TRUE,HttpStatus.OK);}else {return new ResponseEntity(HttpStatus.NOT_FOUND);}}

测试一下


spring-data-elasticsearch 操作ES

https://docs.spring.io/spring-data/


我们也可以用Spring给我们提供的封装好的 ElasticsearchTemplate 更方便的操作ES,这里我就不演示了,和data jpa操作很像,比较简单。

https://spring.io/projects/spring-data-elasticsearch

https://github.com/spring-projects/spring-data-elasticsearch


如果也是使用spring boot集成的话,就用 spring-boot-starter-data-elasticsearch 这个maven的依赖,带有starter的这种。


代码

Github: https://github.com/yangshangwei/springBootElasticSearch

Elasticsearch-06 Spring Boot 2.0.9整合ElasticSearch5.6.16相关推荐

  1. spring boot 2.0.3.RELEASE 整合 shiro bug 记录

    spring boot 2.0.3.RELEASE 和 shiro 结合的 bug 纪要: 1.shiro 的过滤器 会出现在所有的过滤链中,尽管该请求不包含在shiro过滤规则中,尽管不会进入shi ...

  2. 【译】Spring Boot 2.0 官方迁移指南

    前提 希望本文档将帮助您把应用程序迁移到 Spring Boot 2.0. 在你开始之前 首先,Spring Boot 2.0 需要 Java 8 或更高版本.不再支持 Java 6 和 7 了. 在 ...

  3. Spring Boot 2.0 迁移指南

    点击上方"朱小厮的博客",选择"设为星标" 回复"666"获取新整理的1000+GB资料 前提 本文档将帮助您把应用程序迁移到 Spring ...

  4. Spring Cloud F Spring Boot 2.0 版本升级说明书

    Spring Boot 2.0 需要 Java 8 或更高版本.不再支持 Java 6 和 7 了 在 Spring Boot 2.0 中,许多配置属性被重新命名/删除,开发人员需要更新 依赖版本 以 ...

  5. spring boot 1.5.4 整合redis、拦截器、过滤器、监听器、静态资源配置(十六)

    上一篇:spring boot 1.5.4 整合webService(十五) 1      Spring Boot整合redis和缓存 Spring Boot中除了对常用的关系型数据库提供了优秀的自动 ...

  6. Spring Boot 3.0.0-M1 Reference Documentation(Spring Boot中文参考文档) 9-16

    9. 数据 Spring Boot与多个数据技术集成,包括SQL和NoSQL. 9.1. SQL数据库 Spring Framework提供扩展支持用于与SQL数据工作,从使用JdbcTemplate ...

  7. Spring Boot 2.0正式发布,升还是不升呢?

    Spring帝国 Spring几乎是每一位Java开发人员都耳熟能详的开发框架,不论您是一名初出茅庐的程序员还是经验丰富的老司机,都会对其有一定的了解或使用经验.在现代企业级应用架构中,Spring技 ...

  8. Spring Boot 2.0 新特性

    作者:贺卓凡 原文:https://mp.weixin.qq.com/s/EWmuzsgHueHcSB0WH-3AQw 以Java 8 为基准 Spring Boot 2.0 要求Java 版本必须8 ...

  9. spring boot 1.5.4 整合 mybatis(十二)

    上一篇:spring boot 1.5.4 整合log4j2(十一) Spring Boot集成Mybatis 更多更详细的配置参考文件:application.properties和<Spri ...

最新文章

  1. 一个Solidity源文件的布局
  2. int和long计算问题
  3. 用python画烟花-python实现烟花小程序
  4. 【CyberSecurityLearning 20】xu ni zhuan yong wang luo
  5. 查看用户过期linux,linux下控制帐户过期的多种方法讲解
  6. 机器学习的练功心法(三)——特征工程
  7. 构建最小JDK Docker镜像 或者直接使用镜像:frolvlad/alpine-oraclejre8:slim
  8. oracle统计每天数据增量,每天的业务数据增量导入oracle库方法讨论
  9. Spring知识点简介
  10. python——argsort函数
  11. 三菱电机NC monitor 序列号申请
  12. 计算机主板测评,性能测试及评测室总结
  13. excel合并两列内容_办公教程:Excel如何快速将两列内容合并成一列
  14. Vue事件修饰符——.prevent 和.passive
  15. 电脑:键盘快捷键的更改(主要以dell笔记本电脑为模拟对象)
  16. 秒杀竞拍屡创网络神话:馅饼还是美丽陷阱
  17. 安全检查监理项目部材料清单
  18. 看完抖音,感觉我穷我活该,跟个废物一样
  19. c语言编程中精度eps是什么,c语言eps是什么意思
  20. 为了实现自动控制处理,需要计算机具有的基础条件是( ),计算机应用基础考试试卷(电大本科)...

热门文章

  1. 图分区技术基本概念【1】
  2. 会议论文影响因子多少_中国学术期刊影响因子年报(2020版)发布|中国心血管杂志影响力指数3年连升...
  3. 最长的可整合子数组的长度
  4. 基于py36的glob模块总结
  5. python笔记 xpinyin
  6. 文巾解题 733. 图像渲染
  7. 文巾解题 19. 删除链表的倒数第 N 个结点
  8. MapReduce初级案例
  9. 从flink-example分析flink组件(1)WordCount batch实战及源码分析
  10. 微服务实战(五):微服务的事件驱动数据管理