spring data elasticsearch 使用


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

如果尚未安裝elasticsearch,可以 參考https://www.cnblogs.com/shaozm/p/8732842.html這篇文章。

一 、原生寫法

連接客戶端

先談談原生的寫法,

 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節點,官方說法是客戶端開啟嗅探之后,會把嗅探到的節點列表把本地覆蓋掉。

 

搜索

因為我是用spring data elasticsearch框架導入的數據,所以這里就不寫index, type的創建,就展示一下搜索的寫法。 

 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();
    }

 

基本搜索解析

這里先談一下基本的搜索

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

  一般來說 elasticsearch 的普通搜索json都是類似  { "query" :  ... }     這樣的,

  首先elasticsearch 的所有搜索基本分成兩種,一個是 過濾 ,一種是查詢 (為了區分我這里稱得分搜索) ,它們區別舉例說明

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

      而得分搜索有一個score分數作為返回依據,比如這個字段匹配的,給你一點分數,那個字段沒匹配,沒分數,綜合所有的分數看是不是達標了,達標了返回,不達標不返回。

類似

 { "query" : {“range” : { ....... }} }

{ "query" : {“term” : { ....... }} }     term是精確查詢,需要完全匹配

屬於過濾搜索

{ "query" : {“match” : { ....... }} }

 { "query" : {“bool” : { ....... }} }

屬於得分搜索

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

 二、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



 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM