Newer
Older
casic-PTZ / casic-common / src / main / java / com / casic / missiles / es / ElasticSearchQuery.java
chaizhuang on 22 Apr 2024 11 KB es
package com.casic.missiles.es;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.ListIterator;

/**
 * ES查询请求体
 *
 * @author zhangyingjie123
 * @since 2020-11-30
 */
public class ElasticSearchQuery {
    private JSONObject body;
    private JSONObject query;
    private JSONObject bool;
    private JSONArray boolMust;
    private JSONArray boolShould;

    private JSONObject filter;
    private JSONObject filterBool;
    private JSONArray filterBoolMust;
    private JSONArray filterBoolMustnot;

    public static final String MUST_FLAG = "1";
    public static final String MUST_NOT_FLAG = "0";

    public static final String QUERY = "query";
    public static final String SHOULD = "should";
    public static final String BOOL = "bool";
    public static final String MUST = "must";
    public static final String MUST_NOT = "must_not";
    public static final String FILTER = "filter";

    //用户嵌套
    private JSONObject boolBuild;
    private JSONArray boolMustBuild;


    /**
     * 生成查询请求体基础结构:
     * {
     * "query": {
     * "bool": {
     * "must" [],
     * "filter": {
     * "bool": {
     * "must": [],
     * "must_not": []
     * }
     * }
     * }
     * }
     * }
     */
    public ElasticSearchQuery() {
        this.body = new JSONObject();
        this.query = this.query();
        this.bool = this.bool();
        this.boolMust = this.boolMust();
        this.boolShould = this.boolShould();
        this.filter = this.filter();
        this.filterBool = this.filterBool();
        this.filterBoolMust = this.filterBoolMust();
        this.filterBoolMustnot = this.filterBoolMustnot();
    }

    public ElasticSearchQuery(JSONObject body) {
        this.body = body;
    }

    public JSONObject getBody() {
        return body;
    }

    private JSONObject query() {
        if (ObjectUtil.isEmpty(this.body.get(QUERY))) {
            this.body.put("query", new JSONObject());
        }
        return this.body.getJSONObject(QUERY);
    }

    private JSONObject bool() {
        JSONObject query = this.query;
        if (ObjectUtil.isEmpty(query.get(BOOL))) {
            query.put(BOOL, new JSONObject());
        }
        return query.getJSONObject(BOOL);
    }

    private JSONArray boolMust() {
        JSONObject bool = this.bool;
        if (ObjectUtil.isEmpty(bool.get(MUST))) {
            bool.put(MUST, new JSONArray());
        }
        return bool.getJSONArray(MUST);
    }

    private JSONObject filter() {
        JSONObject bool = this.bool;
        if (ObjectUtil.isEmpty(bool.get(FILTER))) {
            bool.put(FILTER, new JSONObject());
        }
        return bool.getJSONObject(FILTER);
    }

    private JSONObject filterBool() {
        JSONObject filter = this.filter;
        if (ObjectUtil.isEmpty(filter.get(BOOL))) {
            filter.put(BOOL, new JSONObject());
        }
        return filter.getJSONObject(BOOL);
    }


    private JSONArray filterBoolMust() {
        JSONObject bool = this.filterBool;
        if (ObjectUtil.isEmpty(bool.get(MUST))) {
            bool.put(MUST, new JSONArray());
        }
        return bool.getJSONArray(MUST);
    }

    private JSONArray filterBoolMustnot() {
        JSONObject bool = this.filterBool;
        if (ObjectUtil.isEmpty(bool.get(MUST_NOT))) {
            bool.put(MUST_NOT, new JSONArray());
        }
        return bool.getJSONArray(MUST_NOT);
    }


    /**
     * 条件入口,打开接口
     */
    public void should(JSONObject boolMust) {
        this.boolShould.add(boolMust);
    }

    /**
     * 条件关闭口,将bool中的元素添加到must集合中
     */
    public void endShould() {
        this.filterBoolMust.add(this.boolBuild);
    }

    private JSONArray boolShould() {
        boolBuild = new JSONObject();
        boolBuild.put(BOOL, new JSONObject());
        boolBuild.getJSONObject(BOOL).put(SHOULD, new JSONArray());
        return boolBuild.getJSONObject(BOOL).getJSONArray(SHOULD);
    }

    /**
     * 构建起点,创建JSONOBJECT对象,初始化结构{filter{ bool{must{  }}}}
     */
    public ElasticSearchQuery build() {
        boolBuild = new JSONObject();
        boolBuild.put(BOOL, new JSONObject());
        boolBuild.getJSONObject(BOOL).put(MUST, new JSONArray());
        boolMustBuild = boolBuild.getJSONObject(BOOL).getJSONArray(MUST);
        return this;
    }

    public JSONObject builder() {
        return this.boolBuild;
    }

    public ElasticSearchQuery termBool(String filed, Serializable value) {
        JSONObject filedJson = new JSONObject();
        filedJson.put(filed, value);
        JSONObject term = new JSONObject();
        term.put("term", filedJson);
        boolMustBuild.add(term);
        return this;
    }

    /**
     * 范围条件是否必须
     */
    public ElasticSearchQuery rangeBool(String filed, Serializable from, Serializable to) {
        JSONObject rangeJson = new JSONObject();
        if (ObjectUtil.isNotEmpty(from)) {
            rangeJson.put("from", from);
        }
        if (ObjectUtil.isNotEmpty(to)) {
            rangeJson.put("to", to);
        }
        JSONObject filedJson = new JSONObject();
        filedJson.put(filed, rangeJson);
        JSONObject range = new JSONObject();
        range.put("range", filedJson);
        boolMustBuild.add(range);
        return this;
    }


    public void match(String filed, Serializable value) {
        JSONArray boolMust = this.boolMust;
        JSONObject match = new JSONObject();
        JSONObject filedJson = new JSONObject();
        filedJson.put(filed, value);
        match.put("match", filedJson);
        boolMust.add(match);
    }

    public void matchPhrase(String filed, Serializable value) {
        JSONArray boolMust = this.boolMust;
        JSONObject matchPhrase = new JSONObject();
        JSONObject filedJson = new JSONObject();
        filedJson.put(filed, value);
        matchPhrase.put("match_phrase", filedJson);
        boolMust.add(matchPhrase);
    }

    public void term(String filed, Serializable value) {
        this.term(filed, value, MUST_FLAG);
    }

    public void term(String filed, Serializable value, String mustFlag) {
        JSONObject filedJson = new JSONObject();
        filedJson.put(filed, value);
        JSONObject term = new JSONObject();
        term.put("term", filedJson);
        if (MUST_FLAG.equals(mustFlag)) {
            this.filterBoolMust.add(term);
        }
        if (MUST_NOT_FLAG.equals(mustFlag)) {
            this.filterBoolMustnot.add(term);
        }
    }

    public void terms(String filed, List value) {
        this.terms(filed, value, MUST_FLAG);
    }

    public void terms(String filed, List value, String mustFlag) {
        JSONObject filedJson = new JSONObject();
        filedJson.put(filed, value);
        JSONObject terms = new JSONObject();
        terms.put("terms", filedJson);
        if (MUST_FLAG.equals(mustFlag)) {
            this.filterBoolMust.add(terms);
        }
        if (MUST_NOT_FLAG.equals(mustFlag)) {
            this.filterBoolMustnot.add(terms);
        }
    }

    public void ranges(String filed, Serializable from, Serializable to) {
        this.ranges(filed, from, to, MUST_FLAG);
    }

    public void range(String filed, Serializable from, Serializable to) {
        this.range(filed, from, to, MUST_FLAG);
    }

    public void removeRange() {
        String key = "range";
        if (this.filterBoolMust != null) {
            ListIterator integerListIterator = this.filterBoolMust.listIterator();
            while (integerListIterator.hasNext()){
                Object next = integerListIterator.next();
                if (((JSONObject) next).containsKey(key)) {
                    ((JSONObject) next).remove(key);
                    integerListIterator.remove();
                }
            }
        }
        if (this.filterBoolMustnot != null) {
            ListIterator integerListIterator = this.filterBoolMustnot.listIterator();
            while (integerListIterator.hasNext()){
                Object next = integerListIterator.next();
                if (((JSONObject) next).containsKey(key)) {
                    ((JSONObject) next).remove(key);
                    integerListIterator.remove();
                }
            }
        }

    }

    /**
     * 范围条件是否必须
     */
    public void ranges(String filed, Serializable from, Serializable to, String mustFlag) {
        JSONObject rangeJson = new JSONObject();
        if (ObjectUtil.isNotEmpty(from)) {
            rangeJson.put("gt", from);
        }
        if (ObjectUtil.isNotEmpty(to)) {
            rangeJson.put("lte", to);
        }
        JSONObject filedJson = new JSONObject();
        filedJson.put(filed, rangeJson);
        JSONObject range = new JSONObject();
        range.put("range", filedJson);
        if (MUST_FLAG.equals(mustFlag)) {
            this.filterBoolMust.add(range);
        }
        if (MUST_NOT_FLAG.equals(mustFlag)) {
            this.filterBoolMustnot.add(range);
        }
    }

    /**
     * 范围条件是否必须
     */
    public void range(String filed, Serializable from, Serializable to, String mustFlag) {
        JSONObject rangeJson = new JSONObject();
        if (ObjectUtil.isNotEmpty(from)) {
            rangeJson.put("from", from);
        }
        if (ObjectUtil.isNotEmpty(to)) {
            rangeJson.put("to", to);
        }
        JSONObject filedJson = new JSONObject();
        filedJson.put(filed, rangeJson);
        JSONObject range = new JSONObject();
        range.put("range", filedJson);
        if (MUST_FLAG.equals(mustFlag)) {
            this.filterBoolMust.add(range);
        }
        if (MUST_NOT_FLAG.equals(mustFlag)) {
            this.filterBoolMustnot.add(range);
        }
    }

    public void size(Long size) {
        this.body.put("size", size);
    }

    public void from(int from) {
        this.body.put("from", from);
        if (from > 10000) {
            this.body.put("query", "match_all");
        }
    }

    public void sort(String sort, String order) {
        JSONObject sortJson = new JSONObject();
        JSONObject orderJson = new JSONObject();
        orderJson.put("order", order);
        sortJson.put(sort, orderJson);
        this.body.put("sort", sortJson);
    }

    public void aggs(String aggsName, String filed) {
        JSONObject terms = new JSONObject();
        terms.put("field", filed);
        JSONObject aggsTerms = new JSONObject();
        aggsTerms.put("terms", terms);
        JSONObject aggsBody = new JSONObject();
        aggsBody.put(aggsName, aggsTerms);
        this.body.put("aggs", aggsBody);
    }

    public void aggs(JSONObject aggBody) {
        this.body.put("aggs", aggBody);
    }


    public static void main(String[] args) {
        ElasticSearchQuery query = new ElasticSearchQuery();
        query.matchPhrase("name", "张三");
        query.term("sex", "2");
        List<Long> deptIds = new ArrayList<>();
        deptIds.add(0L);
        deptIds.add(24L);
        query.terms("deptId", deptIds);
        Date date1 = DateUtil.parse("2020-01-01", "yyyy-MM-dd");
        Date date2 = DateUtil.parse("2020-04-01", "yyyy-MM-dd");
        query.range("collTime", date1.getTime(), date2.getTime());
        query.term("collState", "3", MUST_NOT_FLAG);
        query.size(10L);
        query.from(0);
        query.sort("irId", "asc");
        System.out.println(query.getBody().toJSONString());
    }


}