Spring boot中使用Elasticsearch联合查询

加入Elasticsearch依赖:

1
2
3
4
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
</dependency>

在application.yml文件配置Elasticsearch:

1
2
3
4
5
6
spring:
elasticsearch:
rest:
uris: es节点1,es节点2
username: 用户名
password: 密码

推荐使用这种方式。

然后就可以使用下面的代码自动装配Elasticsearch的高级版客户端:

1
2
@Autowired
private RestHighLevelClient restHighLevelClient;

下面举例如何使用bool联合查询:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
private static final String DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS";

public List<MsgStateDTO> queryMsgStateLogFromElasticsearch(String appId, String messageId, String receiver) {
// 使用bool联合查询需要用到BoolQueryBuilder这个构建器,must方法表示完全匹配
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery()
.must(QueryBuilders.termQuery("appId", appId));
if (!StringUtils.isEmpty(messageId)) {
boolQueryBuilder.must(QueryBuilders.termQuery("messageId", messageId));
}
if (!StringUtils.isEmpty(receiver)) {
boolQueryBuilder.must(QueryBuilders.termQuery("receiver", receiver));
}
// 这里使用RangeQueryBuilder进行日期范围查询,‘createTime’是MsgStateDTO类的属性。
// 这里表示查询到此为止3个月前的数据。
RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("createTime.keyword")
.format(DATETIME_FORMAT)
.timeZone("+08:00")
.from(LocalDateTime.now().minusMonths(3).format(DateTimeFormatter.ofPattern(DATETIME_FORMAT)))
.to(LocalDateTime.now().format(DateTimeFormatter.ofPattern(DATETIME_FORMAT)));
// 添加过滤条件
boolQueryBuilder.filter(rangeQueryBuilder);
// 构建完整的查询语句,SearchSourceBuilder构建表示从第0页开始查询10条,并根据@timestamp字段倒序,然后超时10s
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder()
.query(boolQueryBuilder)
.size(10)
.sort(new FieldSortBuilder("@timestamp").order(SortOrder.DESC))
.timeout(new TimeValue(10, TimeUnit.SECONDS));
SearchRequest searchRequest = new SearchRequest();
// 指定日志所在的索引
searchRequest.indices(INDICES_CSP_MSG_STATE);
searchRequest.source(searchSourceBuilder);
log.info("执行Elasticsearch查询:{}", searchSourceBuilder);

List<MsgStateDTO> msgStateDTOList = Collections.emptyList();
try {
// 执行查询
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
// 结果映射
SearchHit[] hits = searchResponse.getHits().getHits();
Set<MsgStateDTO> msgStateDTOSet = new HashSet<>();
for (SearchHit hit : hits) {
MsgStateDTO msgStateDTO = $.json.toObject(hit.getSourceAsString(), MsgStateDTO.class);
msgStateDTOSet.add(msgStateDTO);
}
msgStateDTOList = msgStateDTOSet.stream()
.sorted(Comparator.comparing(MsgStateDTO::getCreateAt).reversed())
.collect(Collectors.toList());
} catch (IOException e) {
log.error("请求日志服务异常", e);
throw new BusinessException("请求日志服务异常");
}
return msgStateDTOList;
}

注释写得比较详细了,不再进一步说明。

以上,如有问题欢迎提出!

如果对您有所帮助,欢迎投食!
0%