ElasticSearch使用 co.elastic.clients 把普通的SQL筛选条件转为ES的查询条件的工具类

引言

公司公共平台数据全部接入了ES中,但是公司曾经有数据权限,是通过sql语句做的过滤,数据进入了ES中也需要按照同样的方式做数据过滤,这里我贴一下工具类

数据SQL转换工具类

package org.jeecg.common.es;

import co.elastic.clients.elasticsearch._types.FieldValue;
import co.elastic.clients.elasticsearch._types.query_dsl.*;
import org.jeecg.common.system.vo.SysPermissionDataRuleModel;
import co.elastic.clients.json.JsonData;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * ES权限控制工具类
 * Author: WangLiang
 * Date: 2023/10/7 11:12
 */
public class ESDataPermissionUtil {


    /**
     * 根据提供的条件map和构造的query拼接过滤条件
     *
     * @param dataRoleMap
     * @param boolQuery
     */
    public static void addFilterRule(Map<String, List<SysPermissionDataRuleModel>> dataRoleMap, BoolQuery.Builder boolQuery) {
        // 过滤数据权限
        // 对拿到的数据进行分组,每一组之间用 and 分割,组内用 or 分割;
        // 例: where (condition1 = x or condition2 < x or condition3 < x) and (condition4 = x or condition5 = x)

        for (Map.Entry<String, List<SysPermissionDataRuleModel>> entry : dataRoleMap.entrySet()) {
            BoolQuery.Builder boolGroupQuery = new BoolQuery.Builder();
            List<SysPermissionDataRuleModel> dataList = entry.getValue();
            List<Query> queryList = new ArrayList<>();
            for (SysPermissionDataRuleModel model : dataList) {
                queryList.add(ruleConvertFilter(model));
            }
            boolGroupQuery.should(queryList);
            boolQuery.filter(f->f.bool(boolGroupQuery.build()));
        }
    }

    /**
     * 根据系统存入的数据过滤规则转换为ES的过滤规则
     * @param model 系统model
     * @return ES的query对象
     */
    private static Query ruleConvertFilter(SysPermissionDataRuleModel model) {
        String condition = model.getRuleConditions();

        Query.Builder query = new Query.Builder();
        if (condition.equals("=")) {
            query.term(t -> t.field(model.getRuleColumn()).value(model.getRuleColumnvalue()));
        } else if (condition.equals(">")) {
            query.range(r -> r.field(model.getRuleColumn()).gt(JsonData.of(model.getRuleColumnvalue())));
        } else if (condition.equals(">=")) {
            query.range(r -> r.field(model.getRuleColumn()).gte(JsonData.of(model.getRuleColumnvalue())));
        } else if (condition.equals("!=")) {
            query.bool(q -> q.mustNot(m -> m.term(t -> t.field(model.getRuleColumn()).value(model.getRuleColumnvalue()))));
        } else if (condition.equals("IN")) {
            List<FieldValue> fields = new ArrayList<>();
            String[] values = model.getRuleColumnvalue().split(",");
            for (String value : values) {
                fields.add(FieldValue.of(value));
            }
            query.terms(t -> t.field(model.getRuleColumnvalue()).terms(ms -> ms.value(fields)));
        } else if (condition.equals("LIKE")) {
            query.wildcard(m -> m.field(model.getRuleColumn()).value("*" + model.getRuleColumnvalue() + "*"));
        } else if (condition.equals("LEFT_LIKE")) {
            query.wildcard(m -> m.field(model.getRuleColumn()).value("*" + model.getRuleColumnvalue()));
        } else if (condition.equals("RIGHT_LIKE")) {
            query.wildcard(m -> m.field(model.getRuleColumn()).value(model.getRuleColumnvalue() + "*"));
        } else if (condition.equals("<")) {
            query.range(r -> r.field(model.getRuleColumn()).lt(JsonData.of(model.getRuleColumnvalue())));
        } else if (condition.equals("<=")) {
            query.range(r -> r.field(model.getRuleColumn()).lte(JsonData.of(model.getRuleColumnvalue())));
        }

        return query.build();
    }
}

搜索方法:

public <T> HitsMetadata<T> fulltextsearch(List<OnlCgformComb> searchConfigList, String keyword, Integer page, Integer limit, boolean isHighLight,Class<T> beanClass) throws Exception {

       if (searchConfigList==null || searchConfigList.size()==0) {
           //test code
           searchConfigList = new ArrayList<>();
           OnlCgformComb obj1 = new OnlCgformComb();
           obj1.setTableName("his_sys_user");
           obj1.getFields().add("realname");
           obj1.getFields().add("username");
           searchConfigList.add(obj1);

           OnlCgformComb obj2 = new OnlCgformComb();
           obj2.setTableName("his_bus_project_summary");
           obj2.getFields().add("fd_name");
           obj2.getFields().add("fd_project_name");
           searchConfigList.add(obj2);

           OnlCgformComb obj3 = new OnlCgformComb();
           obj3.setTableName("his_bus_createtable");
           obj3.getFields().add("fd_name");
           obj3.getFields().add("fd_file");
           searchConfigList.add(obj3);
       }
        String[] keywordarry=keyword.split(" ");
        SearchRequest.Builder builder = new SearchRequest.Builder();
        //设置查询索引
        List<String> indexNameList=new ArrayList<String>();

        BoolQuery.Builder boolMustQuery = new BoolQuery.Builder();
        for (OnlCgformComb searchConfig : searchConfigList )
        {
            indexNameList.add(searchConfig.getTableName());
            List<String> fdnamelist = searchConfig.getFields();//

            BoolQuery.Builder boolQuery = new BoolQuery.Builder();
            boolQuery.must(
                            q -> q.term(m -> m.field("_index").value(searchConfig.getTableName()))
                            );

            // 过滤权限条件
            if( !ObjectUtils.isEmpty(searchConfig.getDataRole()) ){
                Map<String, List<SysPermissionDataRuleModel>> dataRoleMap = searchConfig.getDataRole();
                ESDataPermissionUtil.addFilterRule(dataRoleMap,boolQuery);
            }

            for (String singlekeyword :keywordarry) {
                if (StringUtils.hasText(singlekeyword.trim())) {
                    boolQuery.must(
                            q -> q.multiMatch(multiMatchQueryBuilder -> multiMatchQueryBuilder
                                    .fields(fdnamelist).query(singlekeyword.trim()).operator(Operator.Or).analyzer("ik_smart"))
                    );
                }
            }
            //builder.query(q -> q.multiMatch(multiMatchQueryBuilder -> multiMatch))
            boolMustQuery.should(q -> q.bool(boolQuery.build()));

        }
        builder.query(q -> q.bool(boolMustQuery.build()));
      /*  String  jsonhighlight="{" +
                "    \"pre_tags\": [\"<a>\"]," +
                "    \"post_tags\": [\"</a>\"]," +
                "    \"fields\": {\"*\": {}}" +
                "  }";
        ObjectMapper om = new ObjectMapper();
        var node = om.readTree(jsonhighlight);
        Highlight highlight =Highlight.of(x->x.withJson());
        builder.highlight(highlight);*/
        if (isHighLight) {
            builder.highlight(h -> h.preTags("<font color='red'>").postTags("</font>").fields("*", x -> x));
        }
        builder.allowNoIndices(true).ignoreThrottled(true).ignoreUnavailable(true);
        //分页
        if(page!=null && limit!=null){
            builder.from(page*limit).size(limit);
        }
        SearchResponse<T> response=null;
        ElasticsearchClient client = null;

        try {
            client = ESClientPool.getClient();
            response = client.search(builder.build(), beanClass);
            return response.hits();

        }
        catch (Exception e) {
           // log.error("Exception fulltextsearch"+e.getMessage(), e);
            throw e;
        }
        finally {
            if (client!=null)
            {
                ESClientPool.returnClient(client);
            }
        }
       // return null;
    }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
co.elastic.clients.elasticsearch.core.aggregations 是 Java 客户端 ElasticSearch 的一个聚合(Aggregation)方法,用于对数据进行分析和统计。 具体使用方法可以参考以下示例: ```java import co.elastic.clients.base.*; import co.elastic.clients.elasticsearch.*; import co.elastic.clients.elasticsearch.core.*; import co.elastic.clients.elasticsearch.core.aggregations.*; import co.elastic.clients.elasticsearch.core.aggregations.bucket.*; import co.elastic.clients.elasticsearch.core.aggregations.metrics.*; import java.io.IOException; import java.util.*; public class ElasticSearchAggregationExample { public static void main(String[] args) throws IOException, ApiException { RestClientBuilder restClientBuilder = RestClient.builder( new HttpHost("localhost", 9200, "http") ); ElasticSearch client = new ElasticSearch(restClientBuilder); SearchRequest request = new SearchRequest() .index("my_index") .source(new SearchSource() .query(new MatchAllQuery()) .aggregations(new TermsAggregation("my_terms_agg") .field("my_field") .size(10) .subAggregations(new AvgAggregation("my_avg_agg") .field("my_other_field") ) ) ); SearchResponse response = client.search(request); TermsAggregationResult myTermsAggResult = response.aggregations().terms("my_terms_agg"); for (TermsAggregationEntry entry : myTermsAggResult.buckets()) { String term = entry.keyAsString(); long count = entry.docCount(); AvgAggregationResult myAvgAggResult = entry.aggregations().avg("my_avg_agg"); double avg = myAvgAggResult.value(); System.out.println(term + ": " + count + ", avg: " + avg); } client.close(); } } ``` 这个例子展示了如何使用 co.elastic.clients.elasticsearch.core.aggregations 方法来进行聚合查询。在这个例子中,我们使用了 TermsAggregation 和 AvgAggregation 两个聚合方法,对数据进行了分组和统计。具体步骤为: 1. 创建一个 SearchRequest 对象,并设置索引名称和查询条件。 2. 在查询条件中添加聚合条件。这里使用了 TermsAggregation 来对数据进行分组,然后使用 AvgAggregation 来统计每个分组的平均值。 3. 执行查询,并获取查询结果。 4. 使用聚合结果对象的方法来获取聚合结果,然后对结果进行处理。 需要注意的是,聚合方法的具体参数和用法可以参考 ElasticSearch 官方文档。同时,Java 客户端的版本和 ElasticSearch 的版本也需要匹配,否则可能会出现兼容性问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值