环境:springboot2.3.10.RELEASE + ElasticSearch7.8.0
相关依赖及应用配置
<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-starter-test</artifactId>
<scope>test</scope>
</dependency>
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
spring:
elasticsearch:
rest:
uris:
- http://localhost:9201
---
logging:
level:
com.pack: debug
org.springframework.data.elasticsearch.core: debug
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
数据模型建立
@Document(createIndex = true, indexName = "products", shards = 3, replicas = 1)
public class Product {
@Id
private Long id ;
@Field(analyzer = "ik_max_word", type = FieldType.Text)
private String title ;
@Field(type= FieldType.Keyword)
private String category ;
@Field(type = FieldType.Double)
private Double price ;
@Field(type = FieldType.Keyword, index = false)
private String images ;
@Override
public String toString() {
return "Product [id=" + id + ", title=" + title + ", category=" + category + ", price=" + price + ", images="
+ images + "]";
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
ProductRepository
这里我们只需要继承ElasticsearchRepository即可,是不是和data-jpa一样一样的的。
public interface ProductRepository extends ElasticsearchRepository<Product, Long> {
}
- 1.
- 2.
继承ElasticsearchRepository后 我们也可以像data-jpa一样使用findBy*等语法来写相关查询方法。
- 方法名中支持的关键字
图片
- 方法返回值类型
- List<T>
- Stream<T>
- SearchHits<T>
- List<SearchHit<T>>
- Stream<SearchHit<T>>
- SearchPage<T>
Repository中也支持@Query注解的方式自定义查询字符串。
public interface ProductRepository extends ElasticsearchRepository<Product, Long> {
List<Product> findByTitle(String title) ;
@Query("{\"fuzzy\": {\"title\": \"?0\"}}")
Page<Product> findByTitle(String sex,Pageable pageable);
// 自定义查询
@Query("{\"match\": {\"category\": \"?0\"}}")
Page<Product> findByCategory(String category,Pageable pageable);
// 高亮设置
@Highlight(fields = {@HighlightField(name = "title"), @HighlightField(name = "category")})
List<SearchHit<Product>> findByTitleOrCategory(String title, String category,Pageable pageable) ;
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
除了使用Repository方式,我们还可以使用ElasticsearchRestTemplate的方式请求服务。如下测试
测试
@Resource
private ProductRepository productRepository ;
@Resource
private ElasticsearchRestTemplate elasticTemplate ;
@Test
public void testCreate() {
Product product = new Product() ;
product.setId(3L) ;
product.setCategory("配件") ;
product.setPrice(299.5d) ;
product.setImages("http://www.pack.com/memory.jpg") ;
product.setTitle("很牛逼的内存条") ;
productRepository.save(product) ;
}
@Test
public void testQuery() {
Product product = productRepository.findById(1L).orElse(null) ;
System.out.println(product) ;
}
@Test
public void testFindAll() {
Pageable pageable = PageRequest.of(1, 2) ;
Page<Product> page = productRepository.findAll(pageable) ;
System.out.println(page.getTotalPages() + "\n" + page.getContent()) ;
}
@Test
public void testTermSearch() {
for (Product p : productRepository.findByTitle("Java从入门到精通")) {
System.out.println(p) ;
}
}
@Test
public void testFindByTitle() {
Pageable pageable = PageRequest.of(0, 2) ;
Page<Product> page = productRepository.findByTitle("Java", pageable) ;
System.out.println(page.getTotalPages() + "\n" + page.getContent()) ;
}
@Test
public void testFindByCategory() {
Pageable pageable = PageRequest.of(0, 2) ;
Page<Product> page = productRepository.findByCategory("书籍", pageable) ;
System.out.println(page.getTotalPages() + "\n" + page.getContent()) ;
}
@Test
public void testCriteriaQuery() {
Criteria criteria = new Criteria("price").greaterThan(50).lessThan(80);
Query query = new CriteriaQuery(criteria);
SearchHits<Product> hits = elasticTemplate.search(query, Product.class, IndexCoordinates.of("products")) ;
for (SearchHit<Product> hit : hits) {
System.out.println(hit) ;
}
}
@Test
public void testStringQuery() {
Query query = new StringQuery("{ \"match\": { \"category\": { \"query\": \"配件\" } } } ");
SearchHits<Product> hits = elasticTemplate.search(query, Product.class);
for (SearchHit<Product> hit : hits) {
System.out.println(hit) ;
}
}
@Test
public void testStringQueryFuzzy() {
Query query = new StringQuery("{ \"fuzzy\":{\"title\":{\"value\":\"Java\"}} }");
HighlightQuery highlightQuery = null ;
HighlightBuilder highBuilder = new HighlightBuilder().preTags("<font color='red'>").postTags("</font>").field("title") ;
highlightQuery = new HighlightQuery(highBuilder) ;
query.setHighlightQuery(highlightQuery) ;
SearchHits<Product> hits = elasticTemplate.search(query, Product.class);
for (SearchHit<Product> hit : hits) {
System.out.println(hit + "\n" + hit.getHighlightField("title")) ;
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.
- 75.
- 76.
- 77.
- 78.
- 79.
- 80.
- 81.
- 82.
在启动服务时会自动地为我们创建索引。
我们可以安装Chrome插件 ElasticSearch Head非常方便地查看es的状态及索引信息。
图片
这里我是搭建的集群。
图片