SpringBoot整合ElasticSearch(Jest、D

作者: 后厂村老司机 | 来源:发表于2018-08-31 10:24 被阅读1次

    前言

    spring里有两个比较好用的操作ES的工具,一个是spring data elasticsearch,一个是Jest,前者连接的是es的9300端口(TCP连接,把自己伪装成ES的一个节点);后者连接的是es的9200端口(Http Restful)。

    1、整合Jest

    step1
    搭建SpringBoot项目,引入Jest依赖,和spring data elasticsearch依赖,引入两个依赖是因为Jest使用过程中会用到spring data elasticsearch的一些类,如QueryBuilder。

    <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的连接和端口。如果有认证需要加上用户名密码等,其他配置可以参考官方文档。

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

    step3
    生产环境用到的查询语句一般是复杂的DSL,DSL一般有以下几种查询类型(过滤器)。ES中的每种查询都有对应的QueryBuilder提供。

    • 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设置查询的条件等等。

    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啊等等。

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

    step6
    执行搜索,处理搜索结果。如果你的对象(下面用User)和结果中的JSON串中的字段一一对应,可以使用getSourceAsObjectList来直接绑定,如果不是一一对应的,你也可以自己写一个方法通过fastjson等工具进行绑定!

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

    总结
    使用上面的方法最好单独封装一层,比如抽出已成ESDAO层,专门用于ES查询,这样后期便于维护。

    2、整合Data ElasticSearch

    Spring Data提供了一个叫做Repository的数据访问层抽象。把之前与Redis,Sql,ElasticSearch,MongoDB等交互的代码做了统一管理。参考文档:https://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/,有中文版的可以自己搜索以下。
    step1
    搭建SpringBoot项目,引入一个maven即可

    <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:
      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等。有兴趣的可以去发掘哦!

    相关文章

      网友评论

        本文标题:SpringBoot整合ElasticSearch(Jest、D

        本文链接:https://www.haomeiwen.com/subject/ajxswftx.html