Spring Boot中集成Elasticsearch有几种方式

  • 通过 REST Client 方式 集成 ES 7.*

    <dependency>
      <groupId>org.elasticsearch</groupId>
      <artifactId>elasticsearch</artifactId>
      <version>7.1.1</version>
    </dependency>
    <dependency>
      <groupId>org.elasticsearch.client</groupId>
      <artifactId>elasticsearch-rest-client</artifactId>
      <version>7.1.1</version>
    </dependency>
    <dependency>
      <groupId>org.elasticsearch.client</groupId>
      <artifactId>elasticsearch-rest-high-level-client</artifactId>
      <exclusions>
        <exclusion>
          <groupId>org.elasticsearch</groupId>
          <artifactId>elasticsearch</artifactId>
        </exclusion>
        <exclusion>
          <groupId>org.elasticsearch.client</groupId>
          <artifactId>elasticsearch-rest-client</artifactId>
        </exclusion>
      </exclusions>
      <version>7.1.1</version>
    </dependency>
    
    elasticSearch.host = 你的服务器地址
    elasticSearch.port = 9200
    elasticSearch.client.connectNum=10
    elasticSearch.client.connectPerRoute=50
    
  • 通过 spring-data-elasticsearch 方式 ,SpringBoot 2.2.0.RELEASE 才兼容elasticsearch 7.x , SpringBoot, spring-data-elasticsearch, ES 三者 版本对应关系 - 验证可行

    • 首先引进maven依赖
    <parent>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-parent</artifactId>
      <version>2.2.2.RELEASE</version>
      <relativePath/> <!-- lookup parent from repository -->
    </parent>
    
    <properties>
      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
      <java.version>1.8</java.version>
      <elasticsearch.version>7.4.2</elasticsearch.version>
     <spring.data.elasticsearch.version>3.2.3.RELEASE</spring.data.elasticsearch.version>
    </properties>
    <dependencies>
      <dependency>
        <groupId>org.elasticsearch</groupId>
        <artifactId>elasticsearch</artifactId>
        <version>${elasticsearch.version}</version>
      </dependency>
      <dependency>
        <groupId>org.elasticsearch.client</groupId>
        <artifactId>transport</artifactId>
        <version>${elasticsearch.version}</version>
      </dependency>
      <dependency>
        <groupId>org.elasticsearch.client</groupId>
        <artifactId>elasticsearch-rest-client</artifactId>
        <version>${elasticsearch.version}</version>
      </dependency>
      <dependency>
        <groupId>org.elasticsearch.plugin</groupId>
        <artifactId>transport-netty4-client</artifactId>
        <version>${elasticsearch.version}</version>
      </dependency>
      <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-elasticsearch</artifactId>
        <version>${spring.data.elasticsearch.version}</version>
      </dependency>
      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
      </dependency>
    
    • 配置 properties
    spring.data.elasticsearch.cluster-name=my-application
    #配置9200是通过HTTP连接的端口,9300是TCP连接的端口
    spring.data.elasticsearch.cluster-nodes=192.168.1.134:9300
    
    @Repository
    public interface CommodityRepository extends ElasticsearchRepository<CommodityDomain, String>, Serializable {
    }
    
    // CommodityRepository 支持的方法
    public interface ElasticsearchRepository <T, ID> extends org.springframework.data.elasticsearch.repository.ElasticsearchCrudRepository<T,ID> {
        <S extends T> S index(S s);
        <S extends T> S indexWithoutRefresh(S s);
        Iterable<T> search(QueryBuilder queryBuilder);
        Page<T> search(QueryBuilder queryBuilder, Pageable pageable);
        Page<T> search(SearchQuery searchQuery);
        Page<T> searchSimilar(T t, String[] strings, Pageable pageable);
        void refresh();
        java.lang.Class<T> getEntityClass();
    }
    
    public interface CrudRepository <T, ID> extends org.springframework.data.repository.Repository<T,ID> {
        <S extends T> S save(S s);
        <S extends T> Iterable<S> saveAll(java.lang.Iterable<S> iterable);
        java.util.Optional<T> findById(ID id);
        boolean existsById(ID id);
        java.lang.Iterable<T> findAll();
        java.lang.Iterable<T> findAllById(Iterable<ID> iterable);
        long count();
        void deleteById(ID id);
        void delete(T t);
        void deleteAll(Iterable<? extends T> iterable);
        void deleteAll();
    }
    
    • 使用 CommodityRepository
    @Autowired
    CommodityRepository commodityRepository;
    // 新增一个索引
    String documentId = "123456";
    CommodityDomain sampleEntity1 = new CommodityDomain();
    sampleEntity1.setId(documentId);
    sampleEntity1.setMessage("some message");
    repository.save(sampleEntity1);
    // 批量新增索引
    repository.saveAll(list);
    
    @Autowired
    ElasticSearchTemplate elasticSearchTemplate;
    
    String documentId = "123456";
    SampleEntity sampleEntity = new SampleEntity();
    sampleEntity.setId(documentId);
    sampleEntity.setMessage("some message");
    // 一次只新增一个 索引
    IndexQuery indexQuery = new IndexQueryBuilder()
      .withId(sampleEntity.getId())
      .withObject(sampleEntity).build();
    elasticsearchTemplate.index(indexQuery);
    
    // clazz 索引 不存在
    if(!elasticsearchTemplate.indexExists(clazz)) {
      elasticsearchTemplate.createIndex(clazz);
      elasticsearchTemplate.putMapping(clazz);
    }
    // 批量新增索引,速度非常快
    elasticsearchTemplate.bulkIndex(queries);
    
    // 单字符串全文查询
    SearchQuery searchQuery = new NativeSearchQueryBuilder()
      .withQuery(queryStringQuery("浣溪沙"))
      .withPageable(pageable).build();
    // 查询某个字段中模糊包含目标字符串,使用matchQuery
    earchQuery searchQuery = new NativeSearchQueryBuilder()
      .withQuery(matchQuery("content", "落日熔金"))
      .withPageable(pageable).build();
    //PhraseMatch查询,短语匹配 : match_phrase查询首先解析查询字符串来产生一个词条列表。然后会搜索所有的词条,但只保留包含了所有搜索词条的文档,并且词条的位置要邻接。一个针对短语“中华共和国”的查询不会匹配“中华人民共和国”,因为没有含有邻接在一起的“中华”和“共和国”词条。
    SearchQuery searchQuery = new NativeSearchQueryBuilder()
      .withQuery(matchPhraseQuery("content", "落日熔金"))
      .withPageable(pageable).build();
    // Term 查询: 这个是最严格的匹配,属于低级查询,不进行分词。我们可以用这个来做那种需要==查询的操作,当传userId=1时,会查询出来所有userId为1的集合。通常情况下,我们不会使用term查询,绝大部分情况我们使用ES的目的就是为了使用它的分词模糊查询功能。而term一般适用于做过滤器filter的情况,譬如我们去查询title中包含“浣溪沙”且userId=1时,那么就可以用termQuery("userId", 1)作为查询的filter
    SearchQuery searchQuery = new NativeSearchQueryBuilder()
      .withQuery(termQuery("userId", 1))
      .withPageable(pageable).build();
    // multi_match多个字段匹配某字符串: 如果我们希望title,content两个字段去匹配某个字符串,只要任何一个字段包括该字符串即可,就可以使用multimatch
    SearchQuery searchQuery = new NativeSearchQueryBuilder()
      .withQuery(multiMatchQuery(title, "title", "content"))
      .withPageable(pageable).build();
    // 完全包含查询 : 我们输入“我天”时,ES会把分词后所有包含“我”和“天”的都查询出来,如果我们希望必须是包含了两个字的才能被查询出来,那么我们就需要设置一下Operator ; 无论是matchQuery,multiMatchQuery,queryStringQuery等,都可以设置operator。默认为Or,设置为And后,就会把符合包含所有输入的才查出来
    SearchQuery searchQuery = new NativeSearchQueryBuilder()
      .withQuery(matchQuery("title", title)
                 .operator(MatchQueryBuilder.Operator.AND))
      .build();
    // minimumShouldMatch可以用在match查询中,设置最少匹配了多少百分比的能查询出来 
    SearchQuery searchQuery = new NativeSearchQueryBuilder()
      .withQuery(matchQuery("title", title)
                 .operator(MatchQueryBuilder.Operator.AND)
                 .minimumShouldMatch("75%")
                ).build();
    // 合并查询 : 即boolQuery,可以设置多个条件的查询方式。它的作用是用来组合多个Query,有四种方式来组合,must,mustnot,filter,should。
    // must代表返回的文档必须满足must子句的条件,会参与计算分值;
    // filter代表返回的文档必须满足filter子句的条件,但不会参与计算分值;
    // should代表返回的文档可能满足should子句的条件,也可能不满足,有多个should时满足任何一个就可以, 通过minimum_should_match设置至少满足几个。
    // mustnot 代表必须不满足子句的条件。
    SearchQuery searchQuery = new NativeSearchQueryBuilder()
      .withQuery(boolQuery()   // title包含“XXX”,且userId=“1”
                 .must(termQuery("userId", userId))   
                 .should(rangeQuery("weight").lt(weight)) // 且weight最好小于5的结果
                 .must(matchQuery("title", title))
                ).build();
    elasticSearchTemplate.queryForList(searchQuery, Post.class);
    
    // Query和Filter的区别
    // 1、查询:是在使用query进行查询时的执行环境,比如使用search的时候。在查询上下文中,查询会回答这个问题——“这个文档是否匹配这个查询,它的相关度高么?”ES中索引的数据都会存储一个_score分值,分值越高就代表越匹配。即使lucene使用倒排索引,对于某个搜索的分值计算还是需要一定的时间消耗。
    // 2、过滤器:在使用filter参数时候的执行环境,比如在bool查询中使用Must_not或者filter. 在过滤器上下文中,查询会回答这个问题——“这个文档是否匹配?” 它不会去计算任何分值,也不会关心返回的排序问题,因此效率会高一点。另外,经常使用过滤器,ES会自动的缓存过滤器的内容,这对于查询来说,会提高很多性能。
    
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值