浅谈SpringDataElasticSearch
Spring Data
Spring Data 帮助我们避免了一些样板式代码,比如我们要定义一个接口,可以直接继承接口ElasticSearchRepository接口,这样Spring Data就帮助我们实现了操作documents基础的CURD方法,在ES里index类似RDBMS里table的概念,documents类似table里datarow的概念,所以ElasticSearchRepository默认已经帮我们实现了操作documents的方法。 类似Spring Data JPA,我们也可以根据约定实现自己想要的方法。Maven dependency org.springframework.boot spring-boot-starter-data-elasticsearch 配置映射
这里在实体类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 authors; }定义接口public interface ProductRepository extends ElasticsearchRepository { Product findByName(String name); Page findByName(String name, PageRequest pageRequest); Page 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 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 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); }