浅谈Spring Data ElasticSearch

795 阅读1分钟

Spring Data

Spring Data 帮助我们避免了一些样板式代码,比如我们要定义一个接口,可以直接继承接口ElasticSearchRepository接口,这样Spring Data就帮助我们实现了操作documents基础的CURD方法,在ES里index类似RDBMS里table的概念,documents类似table里datarow的概念,所以ElasticSearchRepository默认已经帮我们实现了操作documents的方法。 类似Spring Jpa,我们也可以根据约定实现自己想要的方法。

Maven dependency

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>

配置映射

这里在实体类Product上使用了Document注解,配置了index名称,index就相当于一张表。

@Document(indexName = "productindex")
public class Product {
    @Id
    private String id;

    @Field(type = FieldType.Text, name = "name")
    private String name;

    @Field(type = FieldType.Double, name = "price")
    private Double price;

    @Field(type = FieldType.Integer, name = "quantity")
    private Integer quantity;

    @Field(type = FieldType.Keyword, name = "category")
    private String category;

    @Field(type = FieldType.Keyword, name = "desc")
    private String description;

    @Field(type = FieldType.Date, name = "createdDateTime")
    private LocalDate createdDateTime;

    @Field(type = FieldType.Nested, includeInParent = true)
    private List<Author> authors;
}

定义接口

public interface ProductRepository extends ElasticsearchRepository<Product, String> {
    Product findByName(String name);

    Page<Product> findByName(String name, PageRequest pageRequest);
    
    Page<Product> findByNameContaining(String name, PageRequest pageRequest);
}

java 配置

@Configuration
@EnableElasticsearchRepositories(basePackages = "com.shanxi.springbootes.repository")
@ComponentScan(basePackages = {"com.shanxi.springbootes"})
public class ElasticSearchConfig extends AbstractElasticsearchConfiguration {

    @Override
    @Bean
    public RestHighLevelClient elasticsearchClient() {
        ClientConfiguration config = ClientConfiguration
                .builder()
                .connectedTo("localhost:9200")
                .build();

        return RestClients.create(config).rest();
    }

    @Bean
    public ElasticsearchRestTemplate elasticsearchRestTemplate(){
        return new ElasticsearchRestTemplate(elasticsearchClient());
    }
}

创建index和documents

Spring Data ElasticSearch默认已经自动帮助我们创建index,我们也可以手动通过程序创建index。

创建和删除index

//创建index
this.elasticsearchRestTemplate.indexOps(Product.class).create();

//删除index
this.elasticsearchRestTemplate.indexOps(Product.class).delete();

创建documents

 @Test
 public void it_should_create_product_documents_successful(){
     List<Product> products = new ArrayList<>();

     for(int i =1;i<=30;i++){
            Product product =new Product();

            product.setName("python"+i)
                    .setPrice(30d)
                    .setQuantity(10)
                    .setCategory("book"+i)
                    .setDescription("a nice book"+i)
                    .setCreatedDateTime(LocalDate.now())
            ;

            product.setAuthors(Arrays.asList(new Author("李雷"),new Author("韩梅梅")));

            products.add(product);
     }

     this.productRepository.saveAll(products);
     Assertions.assertEquals(products.size(),30);
}

编辑documents

 @Test
 public void it_should_update_Product_successful(){
    Product product =  this.productRepository.findByName("python1");
    product.setQuantity(15);

    this.productRepository.save(product);

    Assertions.assertEquals(15, product.getQuantity());

 }

删除documents

@Test
public void it_should_delete_Product_successful(){
    Product product = this.productRepository.findById("ygnG3n4B9LwueG0uoDc2").get();
    this.productRepository.delete(product);
}

查询documents

精确查询

 @Test
 public void it_should_call_findBy_successful(){
    Product product = this.productRepository.findByName("python2");

    Assertions.assertEquals(product.getQuantity(),10);
    Assertions.assertEquals(product.getPrice(),30d);
 }

匹配查询

这个方法使用Name模糊查询,并且支持分页。

@Test
public void it_should_call_findByNameContaining_success(){
    Page<Product> page = this.productRepository.findByNameContaining("python", PageRequest.of(1,10));
    for (Product product : page.toList()) {
        System.out.println(product.toString());
    }

    Assertions.assertEquals(page.toList().size(),10);
}