SpringBoot整合ElasticSearch(Jest、Data ElasticSearch)

前言

spring裏有兩個比較好用的操做ES的工具,一個是spring data elasticsearch,一個是Jest,前者鏈接的是es的9300端口(TCP鏈接,把本身假裝成ES的一個節點);後者鏈接的是es的9200端口(Http Restful)。html

一、整合Jest

step1
搭建SpringBoot項目,引入Jest依賴,和spring data elasticsearch依賴,引入兩個依賴是由於Jest使用過程當中會用到spring data elasticsearch的一些類,如QueryBuilder。java

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<dependency>
    <groupId>io.searchbox</groupId>
    <artifactId>jest</artifactId>
    <version>5.3.3</version>
</dependency>

step2
application.yml裏面配置ES的鏈接和端口。若是有認證須要加上用戶名密碼等,其餘配置能夠參考官方文檔。node

spring:
  elasticsearch:
    jest:
      uris: http://166.66.66.266:9200

step3
生產環境用到的查詢語句通常是複雜的DSL,DSL通常有如下幾種查詢類型(過濾器)。ES中的每種查詢都有對應的QueryBuilder提供。spring

  • term/terms:精確查找。下面用到了terms查詢,查找loglevel是ERROR或者FATAL的文檔。記住精確查找用termQuery/termsQuery構建就好了,方法ide會給提示
QueryBuilder levelClause = QueryBuilders.termsQuery("loglevel.keyword", "ERROR", "FATAL");
  • range:範圍查找。下面的查詢是找出logtime從startTime到endTime的全部文檔。記住範圍查找用rangeQuery構建就好了
QueryBuilder timeClause = QueryBuilders.rangeQuery("logtime.keyword").from(startTime).to(endTime);
QueryBuilder queryBuilder = QueryBuilders.matchQuery("logclass.keyword","com.huohuo.Test").;
  • and/or/not等:涉及到多條件查詢用boolQuery,組合多個query。must表示and,mustNot表示not,should表示or。
QueryBuilder allClause = QueryBuilders.boolQuery().must(timeClause).must(levelClause);

step4
條件構建完成以後須要配置下搜索器SearchSourceBuilder。搜索器經過size設置搜索多少條記錄,from設置從第幾條開始,fetchSource設置取回哪些字段,timeout設置搜索超時時間,query設置查詢的條件等等。json

SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
String[] sources = {"source", "hostname", "class", "content", "content", "logtime"};
searchSourceBuilder.query(allClause)
    .fetchSource(sources, null)
    .size(10000)
    .timeout(new TimeValue(10, TimeUnit.SECONDS));

step5
搜索器構造完成了,下面開始搜索?nonono!你得告訴搜索器搜索哪一個Index啊,Index下的哪一個Type啊等等。app

Search search = new Search.Builder(searchSourceBuilder.toString())
                .addIndex(esIndex)
                .addType("doc")
                .build();

step6
執行搜索,處理搜索結果。若是你的對象(下面用User)和結果中的JSON串中的字段一一對應,可使用getSourceAsObjectList來直接綁定,若是不是一一對應的,你也能夠本身寫一個方法經過fastjson等工具進行綁定!elasticsearch

SearchResult result = jestClient.execute(search);
List<Log> list = result.getSourceAsObjectList(Log.class,true);
List<String> docList = result.getSourceAsStringList();
esInfoList = parseDocListToBeanList(docList);

總結
使用上面的方法最好單獨封裝一層,好比抽出已成ESDAO層,專門用於ES查詢,這樣後期便於維護。maven

二、整合Data ElasticSearch

Spring Data提供了一個叫作Repository的數據訪問層抽象。把以前與Redis,Sql,ElasticSearch,MongoDB等交互的代碼作了統一管理。參考文檔:https://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/,有中文版的能夠本身搜索如下。
step1
搭建SpringBoot項目,引入一個maven便可ide

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>

step2
配置application.yml文件。端口必定要9300,9300表示TCP端口,ES用java編寫,使用9300至關於假裝成ES的一個節點。9200是給Restful請求提供的接口,http協議的。spring-boot

spring:
  data:
    elasticsearch:
      cluster-nodes: localhost:9300

step3
構建Entity,Entity對象與ES中的doc一一對應,@Data使用了lombok,indexName是索引名稱,type是文檔類型,Id指明文檔惟一標識

@Data
@Document(indexName = "users",type = "User")
public class User {
    @Id
    private Integer id;
    private String userName;
    private String password;
    private String phoneNumber;
    private String address;
    private Integer age;
    private Date hireDate;
}

step4
繼承ESRepository接口便可完成數據交互層的編寫,UserRepository上不用加註解,其餘SpringBean能夠自由的@Autowire注入該類。該類中也能夠加一些本身的方法,方法名字是有規範的,參考文檔裏的就行。

/**
 * @Author: 小混蛋
 * @CreateDate: 2018/8/30 16:54
 */
public interface UserRepository extends ElasticsearchRepository<User,Integer> {
    List<User> findUserByPhoneNumber(String phoneNumber);
}

測試類,發現可行。

@RestController
public class UserService {
    @Autowired
    private UserRepository userRepository;

    @GetMapping("/testSave")
    public void testSave(){
        User user = new User();
        user.setId(1);
        user.setAge(10);
        user.setUserName("小娜");
        user.setHireDate(new Date());
        user.setPassword("secret");
        user.setAddress("大於");
        user.setPhoneNumber("13888888888");
        userRepository.save(user);
    }
    @GetMapping("testGet")
    public Iterable<User> testFind(){
        Iterable<User> all = userRepository.findUserByPhoneNumber("13888888888");
        for(User user : all){
            System.out.println(user);
        }
        return all;
    }
}

總結

Spring data還有不少其餘工具,如RedisTemplate,JPA等。有興趣的能夠去發掘哦!

相關文章
相關標籤/搜索