前言
因为公司的项目是用的 jdk1.7 的,而 Elasticsearch java api client 中,构造查询的条件使用的是 lambda,需要 jdk 8 以上,所以只能放弃,考虑到 High Level Rest Client 在 es 7.15 后弃用,所以用Low Level Rest Client 重新实现以下。
使用
有一个需求是想做es的监控,并发出告警,其中一个步骤是接收查询的参数,构造查询条件,参数类型大致为:
参数:
index(索引名)
时间范围:startTime - endTime
查询类型:精确查询,模糊查询
查询key: 对应 index中的field (可以理解为字段名的意思)
查询value: 自定义的内容
对于 Low Level Rest Client 来说,没有像 High Level Rest Client 那种构造查询条件的 SearchSourceBuilder,所以只好自己封装一个较为简单的查询构造器。
实现过程:
主要是想封装一个json的请求体,作为参数,到es中查询
/**
* @Author: jiafa
* @Date: 2022/3/24 18:00
*/
public interface Query {
}
/**
* @Author: jiafa
* @Date: 2022/3/24 17:31
*/
public class MatchEntity implements Query {
private Map<String, String> match;
public MatchEntity(Map<String, String> match) {
this.match = match;
}
public MatchEntity() {
}
public Map<String, String> getMatch() {
return match;
}
public void setMatch(Map<String, String> match) {
this.match = match;
}
}
/**
* @Author: jiafa
* @Date: 2022/3/24 17:31
*/
public class FuzzyEntity implements Query{
private Map<String, Map<String, String>> fuzzy;
public FuzzyEntity(Map<String, Map<String, String>> fuzzy) {
this.fuzzy = fuzzy;
}
public FuzzyEntity() {
}
public Map<String, Map<String, String>> getFuzzy() {
return fuzzy;
}
public void setFuzzy(Map<String, Map<String, String>> fuzzy) {
this.fuzzy = fuzzy;
}
}
/**
* @Author: jiafa
* @Date: 2022/3/24 17:42
*/
public class RangeEntity implements Query{
private Map<String, Map<String, String>> range;
public RangeEntity(Map<String, Map<String, String>> range) {
this.range = range;
}
public RangeEntity() {
}
public Map<String, Map<String, String>> getRange() {
return range;
}
public void setRange(Map<String, Map<String, String>> range) {
this.range = range;
}
}
/**
* @Author: jiafa
* @Date: 2022/3/24 17:08
*/
public class BoolEntity implements Query {
private List<Query> must;
public BoolEntity(List<Query> must) {
this.must = must;
}
public BoolEntity() {
}
public List<Query> getMust() {
return must;
}
public void setMust(List<Query> must) {
this.must = must;
}
}
/**
* @Author: jiafa
* @Date: 2022/3/24 17:04
*/
public class QueryEntity implements Query{
private Query bool;
public QueryEntity(Query bool) {
this.bool = bool;
}
public QueryEntity() {
}
public Query getBool() {
return bool;
}
public void setBool(Query bool) {
this.bool = bool;
}
}
/**
* @Author: jiafa
* @Date: 2022/3/24 19:36
*/
public class RequestEntity {
Query query;
public RequestEntity(Query query) {
this.query = query;
}
public RequestEntity() {
}
public void setQuery(Query query) {
this.query = query;
}
}
/**
* @Author: jiafa
* @Date: 2022/3/22 15:21
*/
public class QueryESReq {
private String index;
private String startTime;
private String endTime;
private Map<String, String> match;
private Map<String, String> fuzzy;
getter()、setter() and toString();
}
/**
* @Author: jiafa
* @Date: 2022/3/24 15:03
*/
public class LowLevelClietTest {
public static void main(String[] args) {
// 构造查询条件
String taskJson = "{\n" +
" "index": "log-2022-03-23",\n" +
" "startTime": "2022-03-23",\n" +
" "endTime": "2022-03-23",\n" +
" "match": {\n" +
" "host.name": "125.90.88.74",\n" +
" "agent.id": "4892d8e2-8163-4356-914f-c35f10b906e2"\n" +
" },\n" +
" "fuzzy": {\n" +
" "message": "commitSiza" \n" +
" }\n" +
"}";
Gson gson = new GsonBuilder().setPrettyPrinting().create();
QueryESReq req = gson.fromJson(taskJson, QueryESReq.class);
// 获取查询参数
String str = getQueryArgs(req);
// 登录模块
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY,
new UsernamePasswordCredentials("elastic", "密码"));
RestClient client = RestClient
.builder(new HttpHost("自己的ip",9200, "http"))
.setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
@Override
public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
httpClientBuilder.disableAuthCaching();
return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
}
})
.build();
HttpEntity entity = new NStringEntity(str, ContentType.APPLICATION_JSON);
try {
Request request = new Request("GET", "/" + req.getIndex() + "/_search");
request.setEntity(entity);
Response response = client.performRequest(request);
String responseBody = EntityUtils.toString(response.getEntity());
JSONObject jsonObject = JSON.parseObject(responseBody);
System.out.println(gson.toJson(jsonObject.get("hits")));
}catch (Exception e) {
e.printStackTrace();
} finally {
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
// 构造查询条件
private static String getQueryArgs(QueryESReq req) {
String startTime = StringUtils.isBlank(req.getStartTime()) ? null : req.getStartTime();
String endTime = StringUtils.isBlank(req.getEndTime()) ? null : req.getEndTime();
Map<String, String> matchMap = CollectionUtils.isEmpty(req.getMatch()) ? null : req.getMatch();
Map<String, String> fuzzyMap = CollectionUtils.isEmpty(req.getFuzzy()) ? null : req.getFuzzy();
List<Query> queryList = new ArrayList<>();
// 添加 match 条件
if(matchMap != null) {
for(String key : matchMap.keySet()) {
Map<String, String> match = new HashMap<>();
match.put(key, matchMap.get(key));
MatchEntity matchEntity = new MatchEntity(match);
queryList.add(matchEntity);
}
}
// 添加 fuzzy 条件
if(fuzzyMap != null) {
for(String key : fuzzyMap.keySet()) {
Map<String, Map<String, String>> fuzzy = new HashMap<>();
Map<String, String> subFuzzy = new HashMap<>();
subFuzzy.put("value", fuzzyMap.get(key));
fuzzy.put("message", subFuzzy);
FuzzyEntity fuzzyEntity = new FuzzyEntity(fuzzy);
queryList.add(fuzzyEntity);
}
}
// 添加 range 条件
if(startTime != null || endTime != null) {
Map<String, Map<String, String>> range = new HashMap<>();
Map<String, String> subRange = new HashMap<>();
if(startTime != null) {
subRange.put("from", startTime);
}
if(endTime != null) {
subRange.put("to", endTime);
}
range.put("@timestamp", subRange);
RangeEntity rangeEntity = new RangeEntity(range);
queryList.add(rangeEntity);
}
BoolEntity bool = new BoolEntity();
bool.setMust(queryList);
QueryEntity query = new QueryEntity();
query.setBool(bool);
RequestEntity request = new RequestEntity();
request.setQuery(query);
return JsonUtil.toJson(request);
}
}
总结
主要是能够将参数转换为能够在kibana上查询的参数即可。