SpringDataElasticsearch使用

277 阅读3分钟

一.版本和工程配置

在使用前,首先要看一下springboot,springdataelasticsearch 和Elasticsearch对应的版本。 新建springboot工程,pom文件如下,这里选用sringboot的版本为2.1.11,es的版本为6.5.4

<?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 https://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.1.11.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.zx.springdata.es</groupId>
    <artifactId>springdata</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springdata</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <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-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <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>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

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

</project>

配置application.properties,这里需要根据springdataElasticsearch的版本来进行配置,3.1.x及以下的版本还是使用transport client进行通讯,3.2.x开始使用restclient进行通讯,配置项会有所不同

spring.data.elasticsearch.cluster-name=zhenxian
spring.data.elasticsearch.cluster-nodes=127.0.0.1:9300

二.实体类

新建实体类,es测试集群已经新建索引test_ratings,type为doc。实体类中注解@Id用来指定es主键,@Document指定索引名和类型。还可以使用@Field来配置一些和字段相关的属性。

package com.zx.springdata.es.entities;

import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;

import java.io.Serializable;


@Document(indexName = "test_ratings", type = "doc")
public class EsRatings implements Serializable {

    @Id
    private Long id;

    private Long productId;

    private Long rating;

    private String title;

    private Long userId;

    private String comment;

    public EsRatings() {
    }

    public EsRatings(Long id, Long productId, Long rating, String title, Long userId, String comment) {
        this.id = id;
        this.productId = productId;
        this.rating = rating;
        this.title = title;
        this.userId = userId;
        this.comment = comment;
    }

    public Long getId() {
        return id;
    }

    public Long getProductId() {
        return productId;
    }

    public void setProductId(Long productId) {
        this.productId = productId;
    }

    public Long getRating() {
        return rating;
    }

    public void setRating(Long rating) {
        this.rating = rating;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public Long getUserId() {
        return userId;
    }

    public void setUserId(Long userId) {
        this.userId = userId;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getComment() {
        return comment;
    }

    public void setComment(String comment) {
        this.comment = comment;
    }

    @Override
    public String toString() {
        return "EsRatings{" +
                "id=" + id +
                ", productId=" + productId +
                ", rating=" + rating +
                ", title='" + title + '\'' +
                ", userId=" + userId +
                ", comment='" + comment + '\'' +
                '}';
    }
}

三.简单使用

3.1新增

首先新建一个Repository的接口,继承ElasticsearchRepository,这种方式其实和springdata-jpa很相似。

public interface EsRatingsRepository extends ElasticsearchRepository<EsRatings, Long> {
}

通过继承链,我们申明的接口其实已经包含了一些简单的方法,例如save,我们创建一个新增的测试用例。

@Test
    public void add(){
        esRatingsRepository.save(new EsRatings(22333L, 2L, 3L, "喜欢", 2L, "很喜欢"));
    }

利用kibina查询,写入成功

3.2 查询

package com.zx.springdata.es.repository;

import com.zx.springdata.es.entities.EsRatings;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;

public interface EsRatingsRepository extends ElasticsearchRepository<EsRatings, Long> {
    Page<EsRatings> findEsRatingsByCommentAndProductId(String comment, Long productId,Pageable pageable);
}

我们在接口内申明方法,findEsRatingsByCommentAndProductId,springdataElasticsearch会根据方法名,解析为es查询语法。方法的定义中,我们希望根据comment和productId,查询rating记录。

我们写一个测试用例来验证下:

@Test
    public void repoTest(){
        Pageable pageable = PageRequest.of(0,20);
        Page<EsRatings> resut = esRatingsRepository.findEsRatingsByCommentAndProductId("喜欢", 2L, pageable);
        for (EsRatings esRatings : resut){
            System.out.println(esRatings);
        }
    }

查询结果如下:

四.自定义dsl

当使用方法名拼接的方式和接口默认方法不够用的时候,我们还可以使用自定义query的方式。如下,申明方法findByUserId,并利用注解@Query申明查询的dsl

public interface EsRatingsRepository extends ElasticsearchRepository<EsRatings, Long> {
    Page<EsRatings> findEsRatingsByCommentAndProductId(String comment, Long productId,Pageable pageable);

    @Query("{\"term\":{\"userId\":{\"value\":\"?0\"}}}")
    List<EsRatings> findByUserId(Long userId);
}

@Query内的dsl对应,body内query内的dsl。

上面的接口对应dsl

{
  "query": {
    "term": {
      "userId": {
        "value": "2"
      }
    }
  }
}

查询结果:

五.总结

springdataElasticsearch对于快速搭建搜索应用确实比较好用,但是在工业生产当中,会有很多定制化的需求,一般需要我们根据业务,定制访问es的client或者微服务。

更多精彩内容,请关注公众号