spring data elasticsearch 使用

好久以前就安裝了elasticsearch,一直沒用java用過,最近看了一下spring data系列的elasticsearch,這裏寫一篇心得。html

若是還沒有安裝elasticsearch,能夠 參考http://www.javashuo.com/article/p-upmsiepk-gx.html這篇文章。java

一 、原生寫法

鏈接客戶端

先談談原生的寫法,node

 private TransportClient client;
    public TransportClient getClient(){
        Settings setting = Settings.builder()
                .put("cluster.name", "elas_cluster")
                .put("client.transport.ignore_cluster_name", true)
//                    .put("client.transport.nodes_sampler_interval", 5) //
                .put("client.transport.sniff", true)
                .build();

        client = new PreBuiltTransportClient(setting)
                .addTransportAddress(
                        new TransportAddress(new InetSocketAddress("192.168.0.2",9300))
                );
        return  client;

    }

首先鏈接客戶端,這裏單節點和集羣寫法一致,若是是集羣的話也只需配置master節點,官方說法是客戶端開啓嗅探以後,會把嗅探到的節點列表把本地覆蓋掉。git

 

搜索

由於我是用spring data elasticsearch框架導入的數據,因此這裏就不寫index, type的建立,就展現一下搜索的寫法。 github

 public  void  search(){

        QueryBuilder queryBuilder= QueryBuilders.boolQuery()
                .must(QueryBuilders.matchQuery("newsTitle","首個電商俱樂部"))
                .must(QueryBuilders.matchQuery("newsCate","科技"));

        SearchResponse response= client.prepareSearch("test")
                .setTypes("newsArticle")
                .setQuery(queryBuilder).get();
        SearchHits searchHits = response.getHits();
        for(SearchHit searchHit : searchHits) {
            System.out.println(searchHit);
        }

        client.close();
    }

 

基本搜索解析

這裏先談一下基本的搜索redis

  elasticsearch 搜索請求是restful風格的,它的搜索請求都是根據 json格式的參數去搜索的。spring

  通常來講 elasticsearch 的普通搜索json都是相似  { "query" :  ... }     這樣的,json

  首先elasticsearch 的全部搜索基本分紅兩種,一個是 過濾 ,一種是查詢 (爲了區分我這裏稱得分搜索) ,它們區別舉例說明restful

      像過濾搜索判斷都是直接判斷符不符合,好比是否是這個年齡範圍的,這個字段是否是匹配的,是就返回,不是就不返回,框架

      而得分搜索有一個score分數做爲返回依據,好比這個字段匹配的,給你一點分數,那個字段沒匹配,沒分數,綜合全部的分數看是否是達標了,達標了返回,不達標不返回。

相似

 { "query" : {「range」 : { ....... }} }

{ "query" : {「term」 : { ....... }} }     term是精確查詢,須要徹底匹配

屬於過濾搜索

{ "query" : {「match」 : { ....... }} }

 { "query" : {「bool」 : { ....... }} }

屬於得分搜索

 而像{ "query" : {「bool」 : { ....... }} } 這種是組合多個查詢的,其中........ 的內容能夠是多個must 或者should或者must_not或者filter的組合,最終計算score

 2、spring data elasticsearch

準備工做

如今能夠進入主題了,spring data elasticsearch的用法

 先導包

 <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-elasticsearch</artifactId>
            <version>3.1.2.RELEASE</version>
  </dependency>

 接着配置yml

spring:
data: elasticsearch: repositories: enabled:
true cluster-nodes: 192.168.0.2:9300 cluster-name: elas_cluster

 

異常

這裏說一個bug,若是有redis你可能會拋異常,我這裏是在啓動類裏配置了這麼一行

public static void main(String[] args) throws Exception{
    System.setProperty("es.set.netty.runtime.available.processors", "false");
    SpringApplication.run(EsStart.class,args);
}

 

 

使用詳解

spring-data系列的框架,用過jpa的應該都知道套路

首先配置實體註解 

@Document(indexName = "test",type = "newsArticle")
public class NewsArticlePO {
 ......
}

 


若是有什麼字段須要分詞器,能夠單獨在字段上配置
。。。。。。
@Field(type = FieldType.Text, analyzer = "ik_max_word",searchAnalyzer = "ik_max_word")
private String newsTitle;
。。。。。。

 



這時候一啓動項目就會發現index,type已經自動生成了

第二步

建立repository

public interface ArticleRepository extends ElasticsearchRepository<NewsArticlePO,Long> {
   。。。。。。
}

 


這裏有幾種作法,一個是本身利用名字規則定義新的方法,一個是用query註解建立查詢,一個是使用父類繼承的方法。

第一種方法

在 ArticleRepository中建立方法
/**
* 根據標題,類別兩個字段搜索
* */
List<NewsArticlePO> findByNewsTitleAndAndNewsCate(String newsTitle,String newsCate);

 

具體規則參考spring data elasticsearch的官方文檔附錄

第二種方法
在 ArticleRepository中建立方法 
@Query("{\"bool\": {\"must\": [{ \"match\": { \"newsTitle\": \"?0\"}},{ \"match\": { \"newsCate\": \"?1\"}}]}}")
List<NewsArticlePO> findByQuery(String newsTitle, String newsCate);

 


第三種方法
在service層代碼或者其餘類中注入 ArticleRepository
@Resource
private ArticleRepository articleRepository;


建立方法
public Page<NewsArticlePO> searchBuild(String newsTitle, String newsCate) {

    QueryBuilder queryBuilder= QueryBuilders.boolQuery()
            .must(QueryBuilders.matchQuery("newsTitle",newsTitle))
            .must(QueryBuilders.matchQuery("newsCate",newsCate));

    SearchQuery searchQuery = new NativeSearchQueryBuilder()
            .withQuery(queryBuilder)
            .build();
    return   articleRepository.search(searchQuery);
}

 



這就ok了,若是不喜歡使用repository也沒事,能夠注入ElasticsearchTemplate
@Resource
private ElasticsearchTemplate elasticsearchTemplate;
public List<NewsArticlePO> searchTemplate(String newsTitle, String newsCate){
    QueryBuilder queryBuilder= QueryBuilders.boolQuery()
            .must(QueryBuilders.matchQuery("newsTitle",newsTitle))
            .must(QueryBuilders.matchQuery("newsCate",newsCate));

    SearchQuery searchQuery = new NativeSearchQueryBuilder()
            .withQuery(queryBuilder)
            .build();
    return elasticsearchTemplate.queryForList(searchQuery,NewsArticlePO.class);
}

 


甚至能夠經過elasticsearchTemplate.getClient()獲得原生的client進行操做

demo項目地址 https://github.com/1160809039/elasticsearch-demo
相關文章
相關標籤/搜索