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);
}