1. 程式人生 > >Elasticsearch學習(3) spring boot整合Elasticsearch的原生方式

Elasticsearch學習(3) spring boot整合Elasticsearch的原生方式

mapper sql thp 項目 分詞 tail sort com eth

前面我們已經介紹了spring boot整合Elasticsearch的jpa方式,這種方式雖然簡便,但是依舊無法解決我們較為復雜的業務,所以原生的實現方式學習能夠解決這些問題,而原生的學習方式也是Elasticsearch聚合操作的一個基礎。

一、修改spring boot 的application.properties配置文件

##端口號
server.port=8880
##es地址
spring.data.elasticsearch.cluster-nodes =127.0.0.1:9300

需要註意的是:如果你的項目中只配置了Elasticsearch的依賴或者是其他nosql的依賴,那麽就要在spring boot啟動類中添加@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})註解,這個操作是關閉自動配置數據源文件信息。

二、創建一個Bean層

  和spring boot的jpa方式一樣,我們需要創建一個bean來作為我們的索引,註意indexName和type的值是你需要查找的索引內容。 

技術分享圖片
import org.springframework.data.elasticsearch.annotations.Document;

@Document(indexName = "article",type = "center")
public class Zoo {
            private int id;
            private String animal;
            
private Integer num; private String breeder; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getAnimal() { return animal; }
public void setAnimal(String animal) { this.animal = animal; } public Integer getNum() { return num; } public void setNum(Integer num) { this.num = num; } public String getBreeder() { return breeder; } public void setBreeder(String breeder) { this.breeder = breeder; } public Zoo(int id, String animal, Integer num, String breeder) { super(); this.id = id; this.animal = animal; this.num = num; this.breeder = breeder; } public Zoo() { super(); } }
bean層代碼

三、創建一個dao層

  創建的dao層中不需要我們寫實現的方法,只需要繼承ElasticsearchRepository接口。

技術分享圖片
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;


@Configuration
public interface ZooMapper  extends  ElasticsearchRepository<Zoo,Integer>{

}
dao層代碼

四、創建一個Controller層,編寫原生代碼

  一般來說這個操作規範下應該寫到service層,由於是測試項目,我就直接寫在了controller中,我們直接看一個例子

技術分享圖片
import java.util.List;

import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
public class UserController {

    @Autowired
    ZooMapper zooMapper;
    
     // 訪問接口地址:localhost:8880/find    
    //存儲數據
    @GetMapping("find")
    public Object save(){
        
            //1.創建QueryBuilder  可以理解為裝查詢條件的容器
             BoolQueryBuilder builder = QueryBuilders.boolQuery();
             //2.設置查詢條件,參數1:  字段名 參數2:字段值(為什麽中文是一個字而不是詞,這個後面在說)
             QueryBuilder queryBuilder1=QueryBuilders.termQuery("breeder", "飼");
             //設置查詢條件多個匹配,參數1:  字段名     參數2:字段值  參數3:字段值
             QueryBuilder queryBuilder2=QueryBuilders.termsQuery("animal", "rabbit","lion");
             
             
             //3.將查詢的條件放入容器中
             //其中 must相當於SQL中的and     should相當於SQL中的or  mustNot相當於SQL中的not
             builder.must(queryBuilder1);
             builder.should(queryBuilder2);
             
             
             //4.設置排序  參數:需要排序字段 DESC表示降序
             FieldSortBuilder sort = SortBuilders.fieldSort("id").order(SortOrder.DESC);
             
            //5.設置分頁,參數1:第幾頁開始(第一頁是0),參數2:顯示的條數 
            //在spring 2.0開始後,使用PageRequest.of創建分頁參數
             PageRequest page =PageRequest.of(0, 2);
            
             
             //6.在設置好查詢條件、排序設置、分頁設置後需要將他們放入NativeSearchQueryBuilder 容器中
             NativeSearchQueryBuilder  nativeSearchQueryBuilder =new NativeSearchQueryBuilder();
             //將查詢條件放入容器中
             nativeSearchQueryBuilder.withQuery(builder);
             //將分頁放入容器中
             nativeSearchQueryBuilder.withPageable(page);
             //將排序放入容器中
             nativeSearchQueryBuilder.withSort(sort);
             //最後將容器組裝後,生產NativeSearchQuery
             //此時 SearchQuery中的sql為
             //select  * from zoo where  breeder="飼養員1號" or animal in("rabbit","lion") ORDER BY id DESC LIMIT 0,2
             SearchQuery  query = nativeSearchQueryBuilder.build();
             System.out.println("查詢的語句:" + query.getQuery().toString());
             //7.開始查詢
             Page<Zoo> listPage = zooMapper.search(query); 
             //獲取總條數
             int total = (int) listPage.getTotalElements();
             //獲取查詢的內容
             List<Zoo> relist = listPage.getContent();
             System.out.println("relist----------------"+relist.toString());
               return relist;
    }
    
    
}
controller層代碼

 在測試之前,我們需要在Elasticsearch中添加一個索引,這個索引和我們剛才創建的bean中配置的indexName和type的值一致。

技術分享圖片

 打開 http://localhost:8888/find,測試我們的代碼:

  技術分享圖片

這樣做原生的實現方式就已經成功了,接下來就將具體介紹代碼中的具體步驟

六、查詢條件的具體步驟 

  這一節主要講解查詢條件的具體功能,在controller中,有這樣一段代碼: 

             //2.設置查詢條件,參數1:  字段名 參數2:字段值(為什麽中文是一個字而不是詞,這個後面在說)
             QueryBuilder queryBuilder1=QueryBuilders.termQuery("breeder", "飼");
             //設置查詢條件多個匹配,參數1:  字段名     參數2:字段值  參數3:字段值
             QueryBuilder queryBuilder2=QueryBuilders.termsQuery("animal", "rabbit","lion");

  在這個步驟我們可以看到breeder的值是中文且中文是一個字而不是詞,這是因為沒有使用分詞器的原因,Elasticsearch默認的分片是將中文分解成一個字,英文是單個單詞:

1 設置查詢條件

//不分詞查詢 參數1: 字段名,參數2:字段查詢值,因為不分詞,所以漢字只能查詢一個字,英語是一個單詞.
  QueryBuilder queryBuilder=QueryBuilders.termQuery("breeder", "飼");
//分詞查詢,采用默認的分詞器
  QueryBuilder queryBuilder2 = QueryBuilders.matchQuery("breeder", "飼養");
//多個匹配的不分詞查詢
  QueryBuilder queryBuilder=QueryBuilders.termsQuery("animal", "rabbit","lion");
//多個匹配的分詞查詢
  QueryBuilder queryBuilder= QueryBuilders.multiMatchQuery("animal", "r", "l");
//匹配所有文件,相當於就沒有設置查詢條件
  QueryBuilder queryBuilder=QueryBuilders.matchAllQuery();

 2模糊查詢

除了設置普通的查詢,elasticsearch還為我們封裝了模糊查詢

                //1.常用的字符串查詢
                //相當於sql中的  breeder like "飼"
                QueryBuilders.queryStringQuery("飼").field("breeder");
                //2.推薦與該文檔相識的文檔
                //參數1:字段名 參數2:文檔內容
                //如果不指定第一個參數,則默認全部,這個是主要用來推薦偏好內容
                QueryBuilders.moreLikeThisQuery(new String[] {"animal"}).addLikeText("rabbit");
                //3.分詞的字段片查詢,比如飼養員1號能夠被中文分詞器分為:飼養員  1 號
                //使用下面的方法就能查詢‘飼養員’這個片段,如果沒有配置分詞器,就查詢全部
                QueryBuilders.prefixQuery("breeder","飼養員 ");
                //4.通配符查詢,支持* 任意字符串;?任意一個字符與sql中的? *類似
                //參數1:字段名 參數2字段值
                QueryBuilders.wildcardQuery("animal","r??b*");

  在第二條偏好文檔設置中有一個偏好的權重問題,如果感興趣可以參考這個博客:https://blog.csdn.net/laigood/article/details/7831713

 3 邏輯查詢 

                //閉區間   相當於id>=2 and id<=5
                QueryBuilder queryBuilder0 = QueryBuilders.rangeQuery("id").from("2").to("5");
                //開區間   相當於id>2 and id<5
                //至於後面兩個參數的值默認為true也就是閉區間
                //如果想半開半閉只需要調整後面兩個參數的值即可
                QueryBuilder queryBuilder1 = QueryBuilders.rangeQuery("id").from("2").to("5").includeUpper(false).includeLower(false);
                //大於   id>2
                QueryBuilder queryBuilder2 = QueryBuilders.rangeQuery("id").gt("2");
                //大於等於  id>=2
                QueryBuilder queryBuilder3 = QueryBuilders.rangeQuery("id").gte("2");
                //小於   id <5
                QueryBuilder queryBuilder4 = QueryBuilders.rangeQuery("id").lt("5");
                //小於等於 id <=5
                QueryBuilder queryBuilder5 = QueryBuilders.rangeQuery("id").lte("5");

以上就是spring boot整合Elasticsearch的原生方式所有實現方式,這個方式主要是後面的聚合查詢的基礎。

Elasticsearch學習(3) spring boot整合Elasticsearch的原生方式