java通过SpringBoot操作elasticsearch实现基本的增删改查

1. 安装es,kibana并启动(记住es集群名称)

2. 在kibana的 Dev Tools 中创建索引(创建一个名称为estest的结构化索引,数据类型定义好的)

css 复制代码
PUT estest
{
  "settings":{
    "number_of_shards": 3,   
    "number_of_replicas": 1    
  },
  "mappings":{
    "student":{
      "properties":{
        "id":{
          "type":"long"
        },
        "name":{
          "type":"text"
        },
        "address":{
          "type":"keyword"
        },
        "age":{
          "type":"integer"
        },
        "date":{
          "type":"date",
          "format":"yyyy-MM-dd HH:mm:ss|| yyy-MM-dd||epoch_millis"
        },
        "url":{
          "type":"text"
        }
      }
    }
  }
}

3. 创建springBoot项目并配置

3.1 引入需要的依赖环境

xml 复制代码
<dependencies>
    <!--Spring Boot Web 基础环境-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!--Spring Boot 测试环境-->
    <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>

    <!--elasticsearch-->
    <dependency>
        <groupId>org.elasticsearch</groupId>
        <artifactId>elasticsearch</artifactId>
        <version>6.8.5</version>
    </dependency>
    <dependency>
        <groupId>org.elasticsearch.client</groupId>
        <artifactId>transport</artifactId>
        <version>6.8.5</version>
    </dependency>
    <dependency>
        <groupId>org.elasticsearch.plugin</groupId>
        <artifactId>transport-netty4-client</artifactId>
        <version>6.8.5</version>
    </dependency>
</dependencies>

3.2 配置application.yml文件

yaml 复制代码
# 配置端口
server:
  port: 8083
# 日志
logging:
  level:
    com.liyh.controller: debug

3.3 配置logback.xml文件(控制台打印日志)

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
    <!-- 彩色日志依赖的渲染类 -->
    <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/>
    <conversionRule conversionWord="wex"
                    converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/>
    <conversionRule conversionWord="wEx"
                    converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/>
    <!-- 彩色日志格式 -->
    <property name="CONSOLE_LOG_PATTERN"
              value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
    <!-- Console 输出设置 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
            <charset>utf8</charset>
        </encoder>
    </appender>

    <!-- 不用彩色控制台输出 -->
    <!--<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            &lt;!&ndash;格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符&ndash;&gt;
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
        </encoder>
    </appender>-->

    <!-- 日志输出级别 -->
    <root level="INFO">
        <appender-ref ref="STDOUT"/>
    </root>
</configuration>

4. 接口测试

4.1 创建 ElasticSearchController

java 复制代码
package com.liyh.controller;
import org.springframework.web.bind.annotation.RestController;/**
 * @Author: liyh
 * @Date: 2020/9/16 17:12
 */
@RestController
public class ElasticSearchController {

    private static int port = 9300;//通过http请求的端口号是9200,通过客户端请求的端口号是9300
    // 使用本地的es,每个测试中的 settings  要换成  Settings.EMPTY
    //private static String host = "localhost";     //elasticsearch的服务器地址
    private static String host = "192.168.2.37";    //elasticsearch的服务器地址

}

4.2 测试连接

接口地址:http://localhost:8083/connect

java 复制代码
@RequestMapping("connect")
public String connect() throws UnknownHostException {
    //1、指定es集群  cluster.name 是固定的key值,docker-cluster是ES集群的名称
    Settings settings = Settings.builder()
        //设置es集群名称
        .put("cluster.name", "docker-cluster")
        //增加嗅探机制,找到es集群
        .put("client.transport.sniff", true)
        .build();
    /*
         * 创建客户端,所有的操作都由客户端开始,这个就好像是JDBC的Connection对象
         * 用完记得要关闭
         */
    //2.创建访问ES服务器的客户端
    TransportClient client = new PreBuiltTransportClient(settings).addTransportAddresses(
        new TransportAddress(InetAddress.getByName(host), port));
    System.out.println("client :  " + client);
    return client.toString();
}

4.3 向es添加数据

接口地址:http://localhost:8083/testInsert

java 复制代码
//插入数据
@RequestMapping("testInsert")
public String testInsert() throws IOException {
    //1、指定es集群  cluster.name 是固定的key值,docker-cluster是ES集群的名称
    Settings settings = Settings.builder().put("cluster.name", "docker-cluster").build();
    //获取es主机中节点的ip地址及端口号(以下是单个节点案例)
    TransportClient client = new PreBuiltTransportClient(settings).addTransportAddresses(
        new TransportAddress(InetAddress.getByName(host), port));
    //将数据转换成文档的格式(后期可以使用java对象,将数据转换成json对象就可以了)
    XContentBuilder doContentBuilder = XContentFactory.jsonBuilder()
        .startObject()
        .field("id", "1") //字段名 : 值
        .field("name", "网民")
        .field("address", "上海虹桥")
        .field("age", "20")
        .field("date", "2018-05-20")
        .field("url", "www.wangmin.com")
        .endObject();
    //添加文档  index1:索引名 blog:类型 10:id
    //.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) 代表插入成功后立即刷新,因为ES中插入数据默认分片要1秒钟后再刷新

    IndexResponse response = client.prepareIndex("estest", "student", "1")
        .setSource(doContentBuilder).setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE).get();
    //打印出CREATED 表示添加成功
    System.out.println(response.status());
    return response.status().toString();
}

4.4 根据id查询es数据

接口地址:http://localhost:8083/testGet/1

less 复制代码
//从es中查询数据
@RequestMapping("testGet/{id}")
public String testGet(@PathVariable("id") String id) throws UnknownHostException {
    //1、指定es集群  cluster.name 是固定的key值,docker-cluster是ES集群的名称
    Settings settings = Settings.builder().put("cluster.name", "docker-cluster").build();
    //获取es主机中节点的ip地址及端口号(以下是单个节点案例)
    TransportClient client = new PreBuiltTransportClient(settings).addTransportAddresses(
        new TransportAddress(InetAddress.getByName(host), port));
    //实现数据查询(指定_id查询) 参数分别是 索引名,类型名  id
    GetResponse getResponse = client.prepareGet("estest", "student",id).get();
    String sourceAsString = getResponse.getSourceAsString();
    System.out.println(sourceAsString);
    client.close();//关闭客户端
    return sourceAsString;
}

4.5 根据id修改es数据

接口地址:http://localhost:8083/testUpdate/1

访问kibana,年龄修改成功

less 复制代码
//修改数据(指定字段进行修改)
@RequestMapping("testUpdate/{id}")
public String testUpdate(@PathVariable("id") String id) throws IOException, InterruptedException, ExecutionException {
    //1、指定es集群  cluster.name 是固定的key值,docker-cluster是ES集群的名称
    Settings settings = Settings.builder().put("cluster.name", "docker-cluster").build();
    //获取es主机中节点的ip地址及端口号(以下是单个节点案例)
    TransportClient client = new PreBuiltTransportClient(settings).addTransportAddresses(
        new TransportAddress(InetAddress.getByName(host), port));
    UpdateRequest request = new UpdateRequest();
    request.index("estest") //索引名
        .type("student") //类型
        .id(id)//id
        .doc(
        XContentFactory.jsonBuilder()
        .startObject()
        .field("age", "33")//要修改的字段 及字段值
        .endObject()
    );
    UpdateResponse response = client.update(request).get();
    //控制台出现OK 代表更新成功
    System.out.println(response.status());
    return response.status().toString();
}

4.6 upsert修改用法:修改数据存在,执行修改,不存在则执行插入

接口地址:http://localhost:8083/testUpsert/2

less 复制代码
//upsert 修改用法:修改数据存在,执行修改,不存在则执行插入
@RequestMapping("testUpsert/{id}")
public String testUpsert(@PathVariable("id") String id) throws IOException, InterruptedException, ExecutionException {
    //1、指定es集群  cluster.name 是固定的key值,docker-cluster是ES集群的名称
    Settings settings = Settings.builder().put("cluster.name", "docker-cluster").build();
    //获取es主机中节点的ip地址及端口号(以下是单个节点案例)
    TransportClient client = new PreBuiltTransportClient(settings).addTransportAddresses(
        new TransportAddress(InetAddress.getByName(host), port));
    IndexRequest request1 = new IndexRequest("estest", "student",id).source(
        XContentFactory.jsonBuilder()
        .startObject()
        .field("id", id) //字段名 : 值
        .field("name", "刘希")
        .field("address", "北京天安门")
        .field("age", "33")
        .field("date", "1990-11-11")
        .field("url", "www.liuxi.com")
        .endObject()
    );
    UpdateRequest request2 = new UpdateRequest("estest", "student",id).doc(
        XContentFactory.jsonBuilder().startObject()
        .field("age", "44")
        .endObject()
    ).upsert(request1);
    UpdateResponse response = client.update(request2).get();
    //控制台出现OK 代表更新成功, 控制台出现CREATED 代表插入成功
    System.out.println(response.status());
    return response.status().toString();
}

4.7 从es中查询所有数据

接口地址:http://localhost:8083/testGetAll

ini 复制代码
//从es中查询所有数据
@RequestMapping("testGetAll")
public String testGetAll() throws UnknownHostException {
    //1、指定es集群  cluster.name 是固定的key值,docker-cluster是ES集群的名称
    Settings settings = Settings.builder().put("cluster.name", "docker-cluster").build();
    //获取es主机中节点的ip地址及端口号(以下是单个节点案例)
    TransportClient client = new PreBuiltTransportClient(settings).addTransportAddresses(
        new TransportAddress(InetAddress.getByName(host), port));
    QueryBuilder qBuilder = QueryBuilders.matchAllQuery();
    SearchResponse sResponse = client.prepareSearch("estest")
        .setQuery(qBuilder)
        .get();
    SearchHits hits = sResponse.getHits();
    for (SearchHit hit : hits) {
        System.out.println(hit.getSourceAsString());
        //将获取的值转换成map的形式
        Map<String, Object> map = hit.getSourceAsMap();
        System.out.println("url = : " + map.get("url"));

        for (String key : map.keySet()) {
            System.out.println(key +" :" +map.get(key));
        }
        System.out.println("==================");
    }
    return "success";
}

4.8 根据id删除es数据

接口地址:http://localhost:8083/testDelete/1

less 复制代码
//删除数据
@RequestMapping("testDelete/{id}")
public String testDelete(@PathVariable("id") String id) throws UnknownHostException {
    //1、指定es集群  cluster.name 是固定的key值,docker-cluster是ES集群的名称
    Settings settings = Settings.builder().put("cluster.name", "docker-cluster").build();
    //获取es主机中节点的ip地址及端口号(以下是单个节点案例)
    TransportClient client = new PreBuiltTransportClient(settings).addTransportAddresses(
        new TransportAddress(InetAddress.getByName(host), port));
    //将数据转换成文档的格式(后期可以使用java对象,将数据转换成json对象就可以了)
    DeleteResponse response = client.prepareDelete("estest", "student", id).get();
    //控制台打印出OK代表删除成功
    System.out.println(response.status());
    return response.status().toString();
}

4.9 完整Controller代码

java 复制代码
package com.liyh.controller;

import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.WriteRequest;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Map;
import java.util.concurrent.ExecutionException;

/**
 * @Author: liyh
 * @Date: 2020/9/16 17:12
 */
@RestController
public class ElasticSearchController {

    private static int port = 9300;//通过http请求的端口号是9200,通过客户端请求的端口号是9300
    // 使用本地的es,每个测试中的 settings  要换成  Settings.EMPTY
    //private static String host = "localhost";     //elasticsearch的服务器地址
    private static String host = "192.168.2.37";    //elasticsearch的服务器地址

    @RequestMapping("connect")
    public String connect() throws UnknownHostException {
        //1、指定es集群  cluster.name 是固定的key值,docker-cluster是ES集群的名称
        Settings settings = Settings.builder()
                //设置es集群名称
                .put("cluster.name", "docker-cluster")
                //增加嗅探机制,找到es集群
                .put("client.transport.sniff", true)
                .build();
        /*
         * 创建客户端,所有的操作都由客户端开始,这个就好像是JDBC的Connection对象
         * 用完记得要关闭
         */
        //2.创建访问ES服务器的客户端
        TransportClient client = new PreBuiltTransportClient(settings).addTransportAddresses(
                new TransportAddress(InetAddress.getByName(host), port));
        System.out.println("client :  " + client);
        return client.toString();
    }

    //从es中查询数据
    @RequestMapping("testGet/{id}")
    public String testGet(@PathVariable("id") String id) throws UnknownHostException {
        //1、指定es集群  cluster.name 是固定的key值,docker-cluster是ES集群的名称
        Settings settings = Settings.builder().put("cluster.name", "docker-cluster").build();
        //获取es主机中节点的ip地址及端口号(以下是单个节点案例)
        TransportClient client = new PreBuiltTransportClient(settings).addTransportAddresses(
                new TransportAddress(InetAddress.getByName(host), port));
        //实现数据查询(指定_id查询) 参数分别是 索引名,类型名  id
        GetResponse getResponse = client.prepareGet("estest", "student",id).get();
        String sourceAsString = getResponse.getSourceAsString();
        System.out.println(sourceAsString);
        client.close();//关闭客户端
        return sourceAsString;
    }

    //从es中查询所有数据
    @RequestMapping("testGetAll")
    public String testGetAll() throws UnknownHostException {
        //1、指定es集群  cluster.name 是固定的key值,docker-cluster是ES集群的名称
        Settings settings = Settings.builder().put("cluster.name", "docker-cluster").build();
        //获取es主机中节点的ip地址及端口号(以下是单个节点案例)
        TransportClient client = new PreBuiltTransportClient(settings).addTransportAddresses(
                new TransportAddress(InetAddress.getByName(host), port));
        QueryBuilder qBuilder = QueryBuilders.matchAllQuery();
        SearchResponse sResponse = client.prepareSearch("estest")
                .setQuery(qBuilder)
                .get();
        SearchHits hits = sResponse.getHits();
        for (SearchHit hit : hits) {
            System.out.println(hit.getSourceAsString());
            //将获取的值转换成map的形式
            Map<String, Object> map = hit.getSourceAsMap();
            System.out.println("url = : " + map.get("url"));

            for (String key : map.keySet()) {
                System.out.println(key +" :" +map.get(key));
            }
            System.out.println("==================");
        }
        return "success";
    }

    //插入数据
    @RequestMapping("testInsert")
    public String testInsert() throws IOException {
        //1、指定es集群  cluster.name 是固定的key值,docker-cluster是ES集群的名称
        Settings settings = Settings.builder().put("cluster.name", "docker-cluster").build();
        //获取es主机中节点的ip地址及端口号(以下是单个节点案例)
        TransportClient client = new PreBuiltTransportClient(settings).addTransportAddresses(
                new TransportAddress(InetAddress.getByName(host), port));
        //将数据转换成文档的格式(后期可以使用java对象,将数据转换成json对象就可以了)
        XContentBuilder doContentBuilder = XContentFactory.jsonBuilder()
                .startObject()
                .field("id", "1") //字段名 : 值
                .field("name", "网民")
                .field("address", "上海虹桥")
                .field("age", "20")
                .field("date", "2018-05-20")
                .field("url", "www.wangmin.com")
                .endObject();
        //添加文档  index1:索引名 blog:类型 10:id
        //.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) 代表插入成功后立即刷新,因为ES中插入数据默认分片要1秒钟后再刷新

        IndexResponse response = client.prepareIndex("estest", "student", "1")
                .setSource(doContentBuilder).setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE).get();
        //打印出CREATED 表示添加成功
        System.out.println(response.status());
        return response.status().toString();
    }

    //删除数据
    @RequestMapping("testDelete/{id}")
    public String testDelete(@PathVariable("id") String id) throws UnknownHostException {
        //1、指定es集群  cluster.name 是固定的key值,docker-cluster是ES集群的名称
        Settings settings = Settings.builder().put("cluster.name", "docker-cluster").build();
        //获取es主机中节点的ip地址及端口号(以下是单个节点案例)
        TransportClient client = new PreBuiltTransportClient(settings).addTransportAddresses(
                new TransportAddress(InetAddress.getByName(host), port));
        //将数据转换成文档的格式(后期可以使用java对象,将数据转换成json对象就可以了)
        DeleteResponse response = client.prepareDelete("estest", "student", id).get();
        //控制台打印出OK代表删除成功
        System.out.println(response.status());
        return response.status().toString();
    }

    //修改数据(指定字段进行修改)
    @RequestMapping("testUpdate/{id}")
    public String testUpdate(@PathVariable("id") String id) throws IOException, InterruptedException, ExecutionException {
        //1、指定es集群  cluster.name 是固定的key值,docker-cluster是ES集群的名称
        Settings settings = Settings.builder().put("cluster.name", "docker-cluster").build();
        //获取es主机中节点的ip地址及端口号(以下是单个节点案例)
        TransportClient client = new PreBuiltTransportClient(settings).addTransportAddresses(
                new TransportAddress(InetAddress.getByName(host), port));
        UpdateRequest request = new UpdateRequest();
        request.index("estest") //索引名
                .type("student") //类型
                .id(id)//id
                .doc(
                        XContentFactory.jsonBuilder()
                                .startObject()
                                .field("age", "33")//要修改的字段 及字段值
                                .endObject()
                );
        UpdateResponse response = client.update(request).get();
        //控制台出现OK 代表更新成功
        System.out.println(response.status());
        return response.status().toString();
    }

    //upsert 修改用法:修改数据存在,执行修改,不存在则执行插入
    @RequestMapping("testUpsert/{id}")
    public String testUpsert(@PathVariable("id") String id) throws IOException, InterruptedException, ExecutionException {
        //1、指定es集群  cluster.name 是固定的key值,docker-cluster是ES集群的名称
        Settings settings = Settings.builder().put("cluster.name", "docker-cluster").build();
        //获取es主机中节点的ip地址及端口号(以下是单个节点案例)
        TransportClient client = new PreBuiltTransportClient(settings).addTransportAddresses(
                new TransportAddress(InetAddress.getByName(host), port));
        IndexRequest request1 = new IndexRequest("estest", "student",id).source(
                XContentFactory.jsonBuilder()
                        .startObject()
                        .field("id", id) //字段名 : 值
                        .field("name", "刘希")
                        .field("address", "北京天安门")
                        .field("age", "33")
                        .field("date", "1990-11-11")
                        .field("url", "www.liuxi.com")
                        .endObject()
        );
        UpdateRequest request2 = new UpdateRequest("estest", "student",id).doc(
                XContentFactory.jsonBuilder().startObject()
                        .field("age", "44")
                        .endObject()
        ).upsert(request1);
        UpdateResponse response = client.update(request2).get();
        //控制台出现OK 代表更新成功, 控制台出现CREATED 代表插入成功
        System.out.println(response.status());
        return response.status().toString();
    }

}

4.10 项目地址

gitee.com/liyhGitee/s...

相关推荐
cjy00011117 小时前
springboot的 nacos 配置获取不到导致启动失败及日志不输出问题
java·spring boot·后端
小江的记录本18 小时前
【事务】Spring Framework核心——事务管理:ACID特性、隔离级别、传播行为、@Transactional底层原理、失效场景
java·数据库·分布式·后端·sql·spring·面试
sheji341618 小时前
【开题答辩全过程】以 基于springboot的校园失物招领系统为例,包含答辩的问题和答案
java·spring boot·后端
程序员cxuan18 小时前
人麻了,谁把我 ssh 干没了
人工智能·后端·程序员
wuyikeer19 小时前
Spring Framework 中文官方文档
java·后端·spring
Victor35619 小时前
MongoDB(61)如何避免大文档带来的性能问题?
后端
Victor35620 小时前
MongoDB(62)如何避免锁定问题?
后端
wuyikeer20 小时前
Spring BOOT 启动参数
java·spring boot·后端
子木HAPPY阳VIP21 小时前
Ubuntu 22.04 VMware 设置固定IP配置
人工智能·后端·目标检测·机器学习·目标跟踪
人间打气筒(Ada)21 小时前
如何基于 Go-kit 开发 Web 应用:从接口层到业务层再到数据层
开发语言·后端·golang