Java之Spring Data Elasticsearch一篇文章从入门到实战

Posted 蓝盒子bluebox

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java之Spring Data Elasticsearch一篇文章从入门到实战相关的知识,希望对你有一定的参考价值。

Elasticsearch提供的Java客户端有一些不太方便的地方:

  • 很多地方需要拼接Json字符串,在java中拼接字符串有多恐怖你应该懂的
  • 需要自己把对象序列化为json存储
  • 查询到结果也需要自己反序列化为对象

因此,我们这里就不讲解原生的Elasticsearch客户端API了。

而是学习Spring提供的套件:Spring Data Elasticsearch。

一、简介

Spring Data Elasticsearch是Spring Data项目下的一个子模块。

查看 Spring Data的官网:http://projects.spring.io/spring-data/

Spring Data 的使命是为数据访问提供熟悉且一致的基于 Spring 的编程模型,同时仍保留底层数据存储的特​​殊特征。

它使使用数据访问技术、关系和非关系数据库、map-reduce 框架和基于云的数据服务变得容易。

这是一个伞形项目,其中包含许多特定于给定数据库的子项目。

这些项目是通过与这些令人兴奋的技术背后的许多公司和开发商合作开发的。

特征

  • 强大的存储库和自定义对象映射抽象

  • 从存储库方法名称派生的动态查询

  • 提供基本属性的实现域基类

  • 支持透明审计(创建、最后更改)

  • 可以集成自定义存储库代码

  • 通过 JavaConfig 和自定义 XML 命名空间轻松集成 Spring

  • 与 Spring MVC 控制器的高级集成

  • 跨店持久化实验支持

1、Spring Data Elasticsearch



Spring Data for Elasticsearch 是 Spring Data 项目的一部分,该项目旨在为新数据存储提供熟悉且一致的基于 Spring 的编程模型,同时保留特定于存储的特性和功能。

Spring Data Elasticsearch 项目提供了与 Elasticsearch 搜索引擎的集成。Spring Data Elasticsearch 的关键功能领域是以 POJO 为中心的模型,用于与 Elastichsearch 文档交互并轻松编写 Repository 样式的数据访问层。

(1)特征

  • Spring 配置支持使用基于 Java 的@Configuration类或用于 ES 客户端实例的 XML 命名空间。

  • ElasticsearchTemplate帮助程序类,可提高执行常见 ES 操作的生产力。包括文档和 POJO 之间的集成对象映射。

  • 功能丰富的对象映射与 Spring 的转换服务集成

  • 基于注释的映射元数据但可扩展以支持其他元数据格式

  • Repository接口的自动实现,包括对自定义查找器方法的支持。

  • 对存储库的 CDI 支持

二、Demo工程的搭建(创建索引)

我们新建一个demo,学习Elasticsearch

在这之前你需要在Linux上安装Elasticsearch:
如果有则不需要安装,入门没有请看我的这篇文章:
https://blog.csdn.net/qq_44757034/article/details/119717907

1、创建一个新的工程



2、引入依赖

(1)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>

    <groupId>com.itzheng.demo</groupId>
    <artifactId>es-demo</artifactId>
    <version>1.0.0-SNAPSHOT</version>

    <name>elasticsearch</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</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>

</project>

(2)application.yml



其中192.168.56.10为你虚拟机或者服务器的ip地址

spring:
  data:
    elasticsearch:
      cluster-name: elasticsearch
      cluster-nodes: 192.168.56.101:9300

3、设置启动类



package com.itzheng;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class EsApplication {
    public static void main(String[] args) {
        SpringApplication.run(EsApplication.class);
    }
}

4、创建实体类


package com.itzheng.es.pojo;

public class Item {

    private Long id;
    private String title;   //标题
    private String category;//分类
    private String brand;//品牌
    private Double price;//价格
    private String images;//图片地址

}

添加依赖

		<dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

完善实体类

package com.itzheng.es.pojo;

import lombok.Data;

@Data
public class Item {
    private Long id;
    private String title;   //标题
    private String category;//分类
    private String brand;//品牌
    private Double price;//价格
    private String images;//图片地址
}

5、创建测试类

(1)创建索引库


package com.itzheng.es.demo;

import com.itzheng.es.pojo.Item;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.test.context.junit4.SpringRunner;
/*
Springboot的@RunWith(SpringRunner.class)
注解的意义在于Test测试类要使用注入的类,比如@Autowired注入的类,
有了@RunWith(SpringRunner.class)这些类才能实例化到spring容器中,自动注入才能生效,
不然直接一个NullPointerExecption

 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class EsTest {
    @Autowired
    ElasticsearchTemplate template;

    @Test
    public void testCreate(){
        template.createIndex(Item.class);//创建索引
    }
}

完善实体类Item,设置在提交到Elasticsearch的时候的索引名称,类型,以及分片

package com.itzheng.es.pojo;

import lombok.Data;
import org.springframework.data.elasticsearch.annotations.Document;

@Data
@Document(indexName = "itzhengitem",type = "item",shards = 1)
public class Item {
    private Long id;
    private String title;   //标题
    private String category;//分类
    private String brand;//品牌
    private Double price;//价格
    private String images;//图片地址
}

(2)指定映射关系

1)添加字段映射(继续完善Item实体类)设置类型和主键

映射

Spring Data通过注解来声明字段的映射属性,有下面的三个注解:

  • @Document 作用在类,标记实体类为文档对象,一般有四个属性
    • indexName:对应索引库名称
    • type:对应在索引库中的类型
    • shards:分片数量,默认5
    • replicas:副本数量,默认1
  • @Id 作用在成员变量,标记一个字段作为id主键
  • @Field 作用在成员变量,标记为文档的字段,并指定字段映射属性:
    • type:字段类型,取值是枚举:FieldType
    • index:是否索引,布尔类型,默认是true
    • store:是否存储,布尔类型,默认是false
    • analyzer:分词器名称

示例:

package com.itzheng.es.pojo;
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
@Data
@Document(indexName = "itzhengitem",type = "item",shards = 1)
@AllArgsConstructor
@NoArgsConstructor
public class Item {
    @Field(type = FieldType.Long)
    @Id
    private Long id;

    @Field(type = FieldType.Text , analyzer = "ik_smart")//设置类型是文本,并指定分词方式为ik_smart
    private String title;   //标题

    @Field(type = FieldType.Keyword)  //Keyword设置当前也是文本类型,但是不设置分词
    private String category;//分类

    @Field(type = FieldType.Keyword)
    private String brand;//品牌

    @Field(type = FieldType.Double)
    private Double price;//价格

    @Field(type = FieldType.Keyword,index = false)//index = false设置当前字段不需要被索引,index = 默认是true
    private String images;//图片地址
}

2)完善测试类,使用映射规则

package com.itzheng.es.demo;

import com.itzheng.es.pojo.Item;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.test.context.junit4.SpringRunner;
/*
Springboot的@RunWith(SpringRunner.class)
注解的意义在于Test测试类要使用注入的类,比如@Autowired注入的类,
有了@RunWith(SpringRunner.class)这些类才能实例化到spring容器中,自动注入才能生效,
不然直接一个NullPointerExecption
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class EsTest {
    @Autowired
    ElasticsearchTemplate template;

    @Test
    public void testCreate(){
        //创建索引库
        template.createIndex(Item.class);//创建索引
        //指定映射关系
        template.putMapping(Item.class);
    }
}

6、运行测试类

(1)运行测试



运行成功

(2)通过Kabina查看

GET itzhengitem

返回结果

{
  "itzhengitem" : {
    "aliases" : { },
    "mappings" : {
      "properties" : {
        "brand" : {
          "type" : "keyword"
        },
        "category" : {
          "type" : "keyword"
        },
        "id" : {
          "type" : "keyword"
        },
        "images" : {
          "type" : "keyword",
          "index" : false
        },
        "price" : {
          "type" : "double"
        },
        "title" : {
          "type" : "text",
          "analyzer" : "ik_smart"
        }
      }
    },
    "settings" : {
      "index" : {
        "routing" : {
          "allocation" : {
            "include" : {
              "_tier_preference" : "data_content"
            }
          }
        },
        "refresh_interval" : "1s",
        "number_of_shards" : "1",
        "provided_name" : "itzhengitem",
        "creation_date" : "1629355397115",
        "store" : {
          "type" : "fs"
        },
        "number_of_replicas" : "1",
        "uuid" : "2cUsvBtgQ4uOARwTuQoHAA",
        "version" : {
          "created" : "7140099"
        }
      }
    }
  }
}

只查看映射

GET itzhengitem/_mapping
{
  "itzhengitem" : {
    "mappings" : {
      "properties" : {
        "brand" : {
          "type" : "keyword"
        },
        "category" : {
          "type" : "keyword"
        },
        "id" : {
          "type" : "keyword"
        },
        "images" : {
          "type" : "keyword",
          "index" : false
        },
        "price" : {
          "type" : "double"
        },
        "title" : {
          "type" : "text",
          "analyzer" : "ik_smart"
        }
      }
    }
  }
}

三、删除索引

1、编写测试方法

package com.itzheng.es.demo;

import com.itzheng.es.pojo.Item;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.test.context.junit4.SpringRunner;
/*
Springboot的@RunWith(SpringRunner.class)
注解的意义在于Test测试类要使用注入的类,比如@Autowired注入的类,
有了@RunWith(SpringRunner.class)这些类才能实例化到spring容器中,自动注入才能生效,
不然直接一个NullPointerExecption
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class EsTest {
    @Autowired
    ElasticsearchTemplate template;

    @Test
    public void testCreate(){
        //创建索引库
        template.createIndex(Item.class);//创建索引
        //指定映射关系
        template.putMapping(Item.class);

    }

    @Test
    public void

以上是关于Java之Spring Data Elasticsearch一篇文章从入门到实战的主要内容,如果未能解决你的问题,请参考以下文章

spring整合Elasticsearch

Spring data elasticsearch使用

Spring Data Elasticsearch自定义@Query,参数超过10个

SpringBoot-spring-data-elasticsearch7.12.0

java之redis篇(spring-data-redis整合)

java之redis篇(spring-data-redis整合)