springboot 整合 elasticsearch

3,373 阅读3分钟

springboot 整合 elasticsearch

pom.xml 引入
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.6.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

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


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

当前使用的 为 6.6.1 , elasticsearch 7.7.1 版本报错
Received handshake message from unsupported version: [5.0.0] minimal compatible version is: [6.8.0]

yml文件引入
spring:
  data:
    elasticsearch:
      cluster-nodes: 127.0.0.1:9300
      cluster-name: my-application ## 表示 集群名字,在es的elasticsearch.yml中查看
      repositories:
        enabled: true
定义对象信息

//dist_account 索引名
// data 类型
@Data
@Document(indexName = "dist_account", type = "data")
public class AccountEs {
    /**
     *
     */
    @Id
    private Integer id;
    private Integer type;
    private String coinCode;
    private Date createTime;
    private Date updateTime;
    private String userCode;
    private String username;
    private String feeAmount;
}
定义接口信息
public interface AccountRepository extends ElasticsearchRepository<AccountEs, Integer> {

}
定义扫描es接口信息
@Configuration
@EnableElasticsearchRepositories(basePackages = "my.elasticsearch")
public class ElasticsearchConfig {
}
执行查询操作
@Autowired
private AccountRepository accountRepository;

/**
 * 执行普通的es查询
 */
public void queryEs(String userCode, String coinCode, List<Integer> typeList, Date startTime, Date endTime){
    
    BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
    //wildcardQuery 表示模糊匹配 相当于 like
    boolQueryBuilder.must(QueryBuilders.wildcardQuery("userCode", String.format("%s%s%s","*",userCode, "*")));
    //termQuery 表示完全匹配 相当于 =
    boolQueryBuilder.must(QueryBuilders.termQuery("coinCode",coinCode));
    //termsQuery 表示完全匹配,相当于in
    boolQueryBuilder.must(QueryBuilders.termsQuery("type", typeList));
    
    //当前 根据时间范围查找
    RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("createTime");
    if (startTime != null){
        boolQueryBuilder.must(rangeQueryBuilder.gte(startTime.getTime()));
    }
    
    if (endTime != null){
        boolQueryBuilder.must(rangeQueryBuilder.lte(endTime.getTime()));
    }
    
    NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
    nativeSearchQueryBuilder.withQuery(boolQueryBuilder);
    
    //排序 按照id进行倒叙排序
    SortBuilder sortBuilder = SortBuilders.fieldSort("id").order(SortOrder.DESC);
    nativeSearchQueryBuilder.withSort(sortBuilder);
    
    //分页 es 是从0开始计算分页
    PageRequest pageRequest = PageRequest.of(0, 10);
    nativeSearchQueryBuilder.withPageable(pageRequest);
    
    NativeSearchQuery nativeSearchQuery = nativeSearchQueryBuilder.build();
    AggregatedPage<AccountEs> resultPage = (AggregatedPage<AccountEs>) accountRepository.search(nativeSearchQuery);
    
    //获取列表
    resultPage.getContent()
    //获取总数
    resultPage.getTotalElements()
}
es 聚合查询
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
... 参数 分页 排序 与普通查询一致

//对字段 feeAmount 进行sum操作  sum_feeAmount 表示查询参数信息
AbstractAggregationBuilder sum = AggregationBuilders.sum("sum_feeAmount").field("feeAmount");
nativeSearchQueryBuilder.addAggregation(sum);

... 获取列表和总数与普通查询一致

InternalSum internalSum = (InternalSum)resultPage.getAggregation("sum_feeAmount");
//表示进行sum操作的结果
double result = internalSum.getValue();

es 聚合分组查询
//在聚合的基础上添加分组 当前按照 coinCode 字段进行分组,统计feeAmount 字段的总数

BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
... 参数 分页 排序 与普通查询一致

AbstractAggregationBuilder sum = AggregationBuilders.sum("sum_feeAmount").field("feeAmount");
AbstractAggregationBuilder group = AggregationBuilders.terms("coinCode_group").field("coinCode").subAggregation(sum);

... 获取列表和总数与普通查询一致

StringTerms stringTerms = resultPage.getAggregations().get("coinCode_group");
List<StringTerms.Bucket> list = stringTerms.getBuckets();
for (StringTerms.Bucket b : list) {
    //表示获取的是分组的名字
    String goupName = b.getKeyAsString()
    //表示的是每个分组下 统计的 feeAmount 的总数
    InternalSum internalSum = b.getAggregations().get("sum_feeAmount");
    double result = internalSum.getValue();
}

es 根据游标查询
@Autowired
private ElasticsearchTemplate elasticsearchTemplate;


... 参数 分页 排序 与普通查询一致

//第一次查询
//scrollId 进行10秒缓存,超过这个时间则根据 scrollId获取不到数据
Page<AccountEs> page = elasticsearchTemplate.startScroll(10000, nativeSearchQuery, AccountEs.class)

//最终的结果列表
List<AccountEs> resultList = new ArrayList<>();
while (true){
    //获取查询结果
    List<AccountEs> accountEsList = page.getContent();
    
    if (!CollectionUtils.isEmpty(accountEsList)){
        resultList.addAll(accountEsList);
        String scrollId = ((ScrolledPage) page).getScrollId();
        //根据scrollId 进行查询
        page = elasticsearchTemplate.continueScroll(scrollId, 10000, AccountEs.class)
    } else {
        break;
    }
}


错误信息

nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'elasticsearchClient' defined in class path resource [org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.elasticsearch.client.transport.TransportClient]: Factory method 'elasticsearchClient' threw exception; nested exception is java.lang.IllegalStateException: availableProcessors is already set to [12], rejecting [12]

解决方式 在main方法中设置下环境变量

System.setProperty("es.set.netty.runtime.available.processors", "false");