Low Level Rest Client 客户端的查询操作

289 阅读3分钟

前言

因为公司的项目是用的 jdk1.7 的,而 Elasticsearch java api client 中,构造查询的条件使用的是 lambda,需要 jdk 8 以上,所以只能放弃,考虑到 High Level Rest Clientes 7.15 后弃用,所以用Low Level Rest Client 重新实现以下。

wlQCyjkYbR.png

使用

有一个需求是想做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上查询的参数即可。