本節講解SpringBoot與Spring-data-elasticsearch整合的入門案例。
一、環境搭建
新建maven項目,名字隨意
pom.xml
- <parent>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-parent</artifactId>
- <version>1.3.1.RELEASE</version>
- </parent>
- <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-starter-test</artifactId>
- </dependency>
- </dependencies>
application.yml
- spring:
- data:
- elasticsearch: #ElasticsearchProperties
- cluster-name: elasticsearch #默認即為elasticsearch
- cluster-nodes: 120.25.194.233:9300 #配置es節點信息,逗號分隔,如果沒有指定,則啟動ClientNode
這些配置的屬性,最終會設置到org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchProperties
這個實體中。
二、創建實體
Spring-data-elasticsearch為我們提供了@Document
、@Field
等注解,如果某個實體需要建立索引,只需要加上這些注解即可。例如以一個文章實體為例:
Article.java
- import java.io.Serializable;
- import java.util.Date;
- import org.springframework.data.annotation.Id;
- import org.springframework.data.elasticsearch.annotations.DateFormat;
- import org.springframework.data.elasticsearch.annotations.Document;
- import org.springframework.data.elasticsearch.annotations.Field;
- @Document(indexName="article_index",type="article",shards=5,replicas=1,indexStoreType="fs",refreshInterval="-1")
- public class Article implements Serializable{
- /**
- *
- */
- private static final long serialVersionUID = 551589397625941750L;
- @Id
- private Long id;
- /**標題*/
- private String title;
- /**摘要*/
- private String abstracts;
- /**內容*/
- private String content;
- /**發表時間*/
- @Field(format=DateFormat.date_time,index=FieldIndex.no,store=true,type=FieldType.Object)
- private Date postTime;
- /**點擊率*/
- private Long clickCount;
- //setters and getters
- //toString
- }
在需要建立索引的類上加上@Document
注解,即表明這個實體需要進行索引。其定義如下:
- @Persistent
- @Inherited
- @Retention(RetentionPolicy.RUNTIME)
- @Target({ElementType.TYPE})
- public @interface Document {
- String indexName();//索引庫的名稱,個人建議以項目的名稱命名
- String type() default "";//類型,個人建議以實體的名稱命名
- short shards() default 5;//默認分區數
- short replicas() default 1;//每個分區默認的備份數
- String refreshInterval() default "1s";//刷新間隔
- String indexStoreType() default "fs";//索引文件存儲類型
- }
加上了@Document
注解之后,默認情況下這個實體中所有的屬性都會被建立索引、並且分詞。
我們通過@Field
注解來進行詳細的指定,如果沒有特殊需求,那么只需要添加@Document即可。在我們的案例中,使用了@Field針對日期屬性postTime上進行了指定。
@Field注解的定義如下:
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.FIELD)
- @Documented
- @Inherited
- public @interface Field {
- FieldType type() default FieldType.Auto;#自動檢測屬性的類型
- FieldIndex index() default FieldIndex.analyzed;#默認情況下分詞
- DateFormat format() default DateFormat.none;
- String pattern() default "";
- boolean store() default false;#默認情況下不存儲原文
- String searchAnalyzer() default "";#指定字段搜索時使用的分詞器
- String indexAnalyzer() default "";#指定字段建立索引時指定的分詞器
- String[] ignoreFields() default {};#如果某個字段需要被忽略
- boolean includeInParent() default false;
- }
需要注意的是,這些默認值指的是我們沒有在我們沒有在屬性上添加@Filed
注解的默認處理。一旦添加了@Filed注解,所有的默認值都不再生效。此外,如果添加了@Filed
注解,那么type
字段必須指定。
三 創建Repository
我們只要編寫一個接口ArticleSearchRepository,來繼承Spring-data-elasticSearch提供的ElasticsearchRepository
即可。
- import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
- import spring.data.elasticsearch.docs.Article;
- //泛型的參數分別是實體類型和主鍵類型
- public interface ArticleSearchRepository extends ElasticsearchRepository<Article, Long>{
- }
四、編寫測試類
1、測試自動創建mapping
ArticleSearchRepositoryTest.java
- @RunWith(SpringJUnit4ClassRunner.class)
- @SpringApplicationConfiguration(classes=Application.class)
- public class ArticleSearchRepositoryTest {
- @Autowired
- private ArticleSearchRepository articleSearchRepository;
- @Test
- public void test(){
- System.out.println("演示初始化");
- }
- }
這個測試僅僅是為了演示應用啟動后,Spring-data-elasticSearch會自動幫我們建立索引庫和創建實體的mapping信息。
當成功啟動之后,通過sense控制台查看映射信息
可以右邊的結果中,的確出現了article的,mapping信息。
默認情況下,在創建mapping信息的時候,只會創建添加了@Field注解的mapping信息。其他沒有添加@Filed注解的字段在保存索引的時候自動確定。
需要注意的是,mapping信息可以自動創建,但是不能自動更新,也就是說,如果需要重新進行mapping映射的話,需要將原來的刪除,再進行mapping映射。讀者可以嘗試一下將postTime的type改為FieldType.long,這種情況下,會自動將日期轉換成時間戳。但是mapping信息不會自動更新,必須將原有的mapping信息刪除之后,才能重新建立映射。
2、測試保存
- @Test
- public void testSave(){
- Article article=new Article();
- article.setId(1L);
- article.setTitle("elasticsearch教程");
- article.setAbstracts("spring-data-elastichSearch");
- article.setContent("SpringBoot與spring-data-elastichSearch整合");
- article.setPostTime(new Date());
- article.setClickCount(100l);
- articleSearchRepository.save(article);
- }
運行程序后,我們首先查看mapping信息有沒有自動創建
此時查看創建的索引結果
限定查詢結果集大小
Spring Data允許開發者使用first和top關鍵字對返回的查詢結果集大小進行限定。fisrt和top需要跟着一個代表返回的結果集的最大大小的數字。如果沒有跟着一個數字,那么返回的結果集大小默認為1。
Example 8.Limiting the result size of query with Top and First(利用first和top限制返回的結果集大小)
User findFirstByOrderByLastnameAsc(); User findTopByOrderByAgeDesc(); Page<User> queryFirst10ByLastname(String lastname, Pageable pageable); Slice<User> findTop3ByLastname(String lastname, Pageable pageable); List<User> findFirst10ByLastname(String lastname, Sort sort); List<User> findTop10ByLastname(String lastname, Pageable pageable);
限制結果集的表達式還支持Distinct關鍵字。並且,當返回的結果集大小限制為1時,Spring Data支持將返回結果包裝到Optional(java 8新增,這是一個可以為null的容器對象。如果值存在則isPresent()方法會返回true,調用get()方法會返回該對象)之中,例子如下:
Optional<User> findFirstByOrderByLastnameAsc();
在查詢用page和slice來進行分頁查詢的情況下,同樣可以使用first和top來對結果集大小進行限制。
注意,如果在使用Sort參數對查詢結果進行排序的基礎上加上對結果集大小的限制,就可以輕易的獲得最大的K個元素或最小的K個元素。
https://es.yemengying.com/4/4.4/4.4.5.html