This is an automated email from the ASF dual-hosted git repository.

morningman pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/master by this push:
     new 070f42c463 [Enhancement](Es): Support config like whether push down to 
es (#16800)
070f42c463 is described below

commit 070f42c4639caa0d62053f085009686e50f4a146
Author: Stalary <stal...@163.com>
AuthorDate: Fri Feb 17 21:56:11 2023 +0800

    [Enhancement](Es): Support config like whether push down to es (#16800)
    
    Support config like whether push down to es and refactor some code
    Like transform to wildcard query and push down to es, this increases the 
cpu consumption of the es,
    I add a switch control it.
---
 docs/en/docs/lakehouse/multi-catalog/es.md         |  19 +-
 docs/zh-CN/docs/lakehouse/multi-catalog/es.md      |  19 +-
 .../main/java/org/apache/doris/catalog/Env.java    |   3 +-
 .../java/org/apache/doris/catalog/EsResource.java  |   7 +
 .../java/org/apache/doris/catalog/EsTable.java     |  12 +
 .../doris/catalog/external/EsExternalTable.java    |   1 +
 .../apache/doris/datasource/EsExternalCatalog.java |   5 +
 .../doris/external/elasticsearch/EsUtil.java       | 203 ---------------
 .../external/elasticsearch/QueryBuilders.java      | 280 ++++++++++++++++++++-
 .../java/org/apache/doris/planner/EsScanNode.java  |   5 +-
 .../doris/external/elasticsearch/EsUtilTest.java   |  89 +++----
 11 files changed, 367 insertions(+), 276 deletions(-)

diff --git a/docs/en/docs/lakehouse/multi-catalog/es.md 
b/docs/en/docs/lakehouse/multi-catalog/es.md
index 0ad296899b..f44dc9cb62 100644
--- a/docs/en/docs/lakehouse/multi-catalog/es.md
+++ b/docs/en/docs/lakehouse/multi-catalog/es.md
@@ -50,16 +50,17 @@ After switching to the ES Catalog, you will be in the 
`dafault_db`  so you don't
 
 ### Parameter Description
 
-| Parameter         | Required or Not | Default Value | Description            
                                      |
-| ----------------- | --------------- | ------------- | 
------------------------------------------------------------ |
-| `hosts`           | Yes             |               | ES address, can be one 
or multiple addresses, or the load balancer address of ES |
-| `user`            | No              | Empty         | ES username            
                                      |
-| `password`        | No              | Empty         | Password of the 
corresponding user                           |
-| `doc_value_scan`  | No              | true          | Whether to obtain 
value of the target field by ES/Lucene columnar storage |
-| `keyword_sniff`   | No              | true          | Whether to sniff the 
text.fields in ES based on keyword; If this is set to false, the system will 
perform matching after tokenization. |
+| Parameter         | Required or Not | Default Value | Description            
                                                                                
                                           |
+| ----------------- | --------------- | ------------- 
|---------------------------------------------------------------------------------------------------------------------------------------------------|
+| `hosts`           | Yes             |               | ES address, can be one 
or multiple addresses, or the load balancer address of ES                       
                                           |
+| `user`            | No              | Empty         | ES username            
                                                                                
                                           |
+| `password`        | No              | Empty         | Password of the 
corresponding user                                                              
                                                  |
+| `doc_value_scan`  | No              | true          | Whether to obtain 
value of the target field by ES/Lucene columnar storage                         
                                                |
+| `keyword_sniff`   | No              | true          | Whether to sniff the 
text.fields in ES based on keyword; If this is set to false, the system will 
perform matching after tokenization.            |
 | `nodes_discovery` | No              | true          | Whether to enable ES 
node discovery, set to true by default; set to false in network isolation 
environments and only connected to specified nodes |
-| `ssl`             | No              | false         | Whether to enable 
HTTPS access mode for ES, currently follows a "Trust All" method in FE/BE |
-| `mapping_es_id`   | No              | false         | Whether to map the  
`_id`  field in the ES index             |
+| `ssl`             | No              | false         | Whether to enable 
HTTPS access mode for ES, currently follows a "Trust All" method in FE/BE       
                                                |
+| `mapping_es_id`   | No              | false         | Whether to map the  
`_id`  field in the ES index                                                    
                                              |
+| `like_push_down`  | No              | true          | Whether to transform 
like to wildcard push down to es, this increases the cpu consumption of the es. 
                                             |
 
 > 1. In terms of authentication, only HTTP Basic authentication is supported 
 > and it requires the user to have read privilege for the index and paths 
 > including `/_cluster/state/` and `_nodes/http` ; if you have not enabled 
 > security authentication for the cluster, you don't need to set the  `user` 
 > and `password`.
 >
diff --git a/docs/zh-CN/docs/lakehouse/multi-catalog/es.md 
b/docs/zh-CN/docs/lakehouse/multi-catalog/es.md
index 68fea116ba..c6225d41b0 100644
--- a/docs/zh-CN/docs/lakehouse/multi-catalog/es.md
+++ b/docs/zh-CN/docs/lakehouse/multi-catalog/es.md
@@ -50,16 +50,17 @@ CREATE CATALOG es PROPERTIES (
 
 ### 参数说明
 
-参数 | 是否必须 | 默认值 | 说明 
---- | --- | --- | --- 
-`hosts` | 是 | | ES 地址,可以是一个或多个,也可以是 ES 的负载均衡地址 |
-`user` | 否 |  空 | ES 用户名 |
-`password` | 否 | 空 | 对应用户的密码信息 |
-`doc_value_scan` | 否 | true | 是否开启通过 ES/Lucene 列式存储获取查询字段的值 |
+参数 | 是否必须 | 默认值 | 说明                                                           
          
+--- | --- | --- 
|------------------------------------------------------------------------
+`hosts` | 是 | | ES 地址,可以是一个或多个,也可以是 ES 的负载均衡地址                                 
        |
+`user` | 否 |  空 | ES 用户名                                                       
          |
+`password` | 否 | 空 | 对应用户的密码信息                                                 
             |
+`doc_value_scan` | 否 | true | 是否开启通过 ES/Lucene 列式存储获取查询字段的值                    
                      |
 `keyword_sniff` | 否 | true | 是否对 ES 中字符串分词类型 text.fields 进行探测,通过 keyword 
进行查询。设置为 false 会按照分词后的内容匹配 |
-`nodes_discovery` | 否 | true | 是否开启 ES 节点发现,默认为 true,在网络隔离环境下设置为 false,只连接指定节点 
|
-`ssl` | 否 | false | ES 是否开启 https 访问模式,目前在 fe/be 实现方式为信任所有 |
-`mapping_es_id` | 否 | false | 是否映射 ES 索引中的 `_id` 字段 |
+`nodes_discovery` | 否 | true | 是否开启 ES 节点发现,默认为 true,在网络隔离环境下设置为 false,只连接指定节点 
                       |
+`ssl` | 否 | false | ES 是否开启 https 访问模式,目前在 fe/be 实现方式为信任所有                     
            |
+`mapping_es_id` | 否 | false | 是否映射 ES 索引中的 `_id` 字段                            
                      |
+`like_push_down` | 否 | true  | 是否将 like 转化为 wildchard 下推到 ES,会增加 ES cpu 消耗     
                       |
 
 > 1. 认证方式目前仅支持 Http Basic 认证,并且需要确保该用户有访问: `/_cluster/state/、_nodes/http` 等路径和 
 > index 的读权限; 集群未开启安全认证,用户名和密码不需要设置。
 > 
diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java
index 6e27a626f2..4e1f10dd3f 100755
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java
@@ -3042,7 +3042,8 @@ public class Env {
             sb.append("\"max_docvalue_fields\" = 
\"").append(esTable.getMaxDocValueFields()).append("\",\n");
             sb.append("\"enable_keyword_sniff\" = 
\"").append(esTable.isEnableKeywordSniff()).append("\",\n");
             sb.append("\"nodes_discovery\" = 
\"").append(esTable.isNodesDiscovery()).append("\",\n");
-            sb.append("\"http_ssl_enabled\" = 
\"").append(esTable.isHttpSslEnabled()).append("\"\n");
+            sb.append("\"http_ssl_enabled\" = 
\"").append(esTable.isHttpSslEnabled()).append("\",\n");
+            sb.append("\"like_push_down\" = 
\"").append(esTable.isLikePushDown()).append("\"\n");
             sb.append(")");
         } else if (table.getType() == TableType.HIVE) {
             HiveTable hiveTable = (HiveTable) table;
diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/EsResource.java 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/EsResource.java
index 012ad119e3..91cb4529ad 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/EsResource.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/EsResource.java
@@ -60,6 +60,8 @@ public class EsResource extends Resource {
     public static final String NODES_DISCOVERY = "nodes_discovery";
     public static final String HTTP_SSL_ENABLED = "http_ssl_enabled";
     public static final String MAPPING_ES_ID = "mapping_es_id";
+
+    public static final String LIKE_PUSH_DOWN = "like_push_down";
     public static final String QUERY_DSL = "query_dsl";
 
     public static final String DOC_VALUE_SCAN_DEFAULT_VALUE = "true";
@@ -67,6 +69,8 @@ public class EsResource extends Resource {
     public static final String HTTP_SSL_ENABLED_DEFAULT_VALUE = "false";
     public static final String NODES_DISCOVERY_DEFAULT_VALUE = "true";
     public static final String MAPPING_ES_ID_DEFAULT_VALUE = "false";
+
+    public static final String LIKE_PUSH_DOWN_DEFAULT_VALUE = "true";
     @SerializedName(value = "properties")
     private Map<String, String> properties;
 
@@ -127,6 +131,9 @@ public class EsResource extends Resource {
         if (properties.containsKey(EsResource.MAPPING_ES_ID)) {
             EsUtil.getBoolean(properties, EsResource.MAPPING_ES_ID);
         }
+        if (properties.containsKey(EsResource.LIKE_PUSH_DOWN)) {
+            EsUtil.getBoolean(properties, EsResource.LIKE_PUSH_DOWN);
+        }
     }
 
     private Map<String, String> processCompatibleProperties(Map<String, 
String> props) {
diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/EsTable.java 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/EsTable.java
index a26a7db7f9..81000c69d1 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/EsTable.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/EsTable.java
@@ -87,10 +87,15 @@ public class EsTable extends Table {
     // would downgrade to extract value from `stored_fields`
     private int maxDocValueFields = DEFAULT_MAX_DOCVALUE_FIELDS;
 
+    // Whether to enable the discovery of es nodes, You can disable it if you 
are in network isolation
     private boolean nodesDiscovery = 
Boolean.parseBoolean(EsResource.NODES_DISCOVERY_DEFAULT_VALUE);
 
+    // Whether to use ssl call es, be and fe access through trust
     private boolean httpSslEnabled = 
Boolean.parseBoolean(EsResource.HTTP_SSL_ENABLED_DEFAULT_VALUE);
 
+    // Whether pushdown like expr, like will trans to wildcard query, consumes 
too many es cpu resources
+    private boolean likePushDown = 
Boolean.parseBoolean(EsResource.LIKE_PUSH_DOWN_DEFAULT_VALUE);
+
     // tableContext is used for being convenient to persist some configuration 
parameters uniformly
     private Map<String, String> tableContext = new HashMap<>();
 
@@ -171,6 +176,10 @@ public class EsTable extends Table {
             httpSslEnabled = EsUtil.getBoolean(properties, 
EsResource.HTTP_SSL_ENABLED);
         }
 
+        if (properties.containsKey(EsResource.LIKE_PUSH_DOWN)) {
+            likePushDown = EsUtil.getBoolean(properties, 
EsResource.LIKE_PUSH_DOWN);
+        }
+
         if (StringUtils.isNotBlank(properties.get(EsResource.TYPE))) {
             mappingType = properties.get(EsResource.TYPE).trim();
         }
@@ -197,6 +206,7 @@ public class EsTable extends Table {
         tableContext.put("maxDocValueFields", 
String.valueOf(maxDocValueFields));
         tableContext.put(EsResource.NODES_DISCOVERY, 
String.valueOf(nodesDiscovery));
         tableContext.put(EsResource.HTTP_SSL_ENABLED, 
String.valueOf(httpSslEnabled));
+        tableContext.put(EsResource.LIKE_PUSH_DOWN, 
String.valueOf(likePushDown));
     }
 
     @Override
@@ -275,6 +285,8 @@ public class EsTable extends Table {
                 EsResource.NODES_DISCOVERY_DEFAULT_VALUE));
         httpSslEnabled = 
Boolean.parseBoolean(tableContext.getOrDefault(EsResource.HTTP_SSL_ENABLED,
                 EsResource.HTTP_SSL_ENABLED_DEFAULT_VALUE));
+        likePushDown = 
Boolean.parseBoolean(tableContext.getOrDefault(EsResource.LIKE_PUSH_DOWN,
+                EsResource.LIKE_PUSH_DOWN_DEFAULT_VALUE));
         PartitionType partType = PartitionType.valueOf(Text.readString(in));
         if (partType == PartitionType.UNPARTITIONED) {
             partitionInfo = SinglePartitionInfo.read(in);
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/catalog/external/EsExternalTable.java
 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/external/EsExternalTable.java
index 4eab32b17a..290917e21c 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/catalog/external/EsExternalTable.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/external/EsExternalTable.java
@@ -96,6 +96,7 @@ public class EsExternalTable extends ExternalTable {
         esTable.setEnableKeywordSniff(esCatalog.enableKeywordSniff());
         esTable.setNodesDiscovery(esCatalog.enableNodesDiscovery());
         esTable.setHttpSslEnabled(esCatalog.enableSsl());
+        esTable.setLikePushDown(esCatalog.enableLikePushDown());
         esTable.setSeeds(esCatalog.getNodes());
         esTable.setHosts(String.join(",", esCatalog.getNodes()));
         esTable.syncTableMetaData();
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/datasource/EsExternalCatalog.java 
b/fe/fe-core/src/main/java/org/apache/doris/datasource/EsExternalCatalog.java
index 390963ae58..650e5374e5 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/datasource/EsExternalCatalog.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/datasource/EsExternalCatalog.java
@@ -106,6 +106,11 @@ public class EsExternalCatalog extends ExternalCatalog {
                 EsResource.MAPPING_ES_ID_DEFAULT_VALUE));
     }
 
+    public boolean enableLikePushDown() {
+        return 
Boolean.parseBoolean(catalogProperty.getOrDefault(EsResource.LIKE_PUSH_DOWN,
+                EsResource.LIKE_PUSH_DOWN_DEFAULT_VALUE));
+    }
+
     @Override
     protected void initLocalObjectsImpl() {
         esRestClient = new EsRestClient(getNodes(), getUsername(), 
getPassword(), enableSsl());
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/external/elasticsearch/EsUtil.java 
b/fe/fe-core/src/main/java/org/apache/doris/external/elasticsearch/EsUtil.java
index 2276356fa8..4dd1991853 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/external/elasticsearch/EsUtil.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/external/elasticsearch/EsUtil.java
@@ -17,32 +17,15 @@
 
 package org.apache.doris.external.elasticsearch;
 
-import org.apache.doris.analysis.BinaryPredicate;
-import org.apache.doris.analysis.BoolLiteral;
-import org.apache.doris.analysis.CastExpr;
-import org.apache.doris.analysis.CompoundPredicate;
-import org.apache.doris.analysis.DecimalLiteral;
 import org.apache.doris.analysis.DistributionDesc;
-import org.apache.doris.analysis.Expr;
-import org.apache.doris.analysis.FloatLiteral;
-import org.apache.doris.analysis.FunctionCallExpr;
-import org.apache.doris.analysis.InPredicate;
-import org.apache.doris.analysis.IntLiteral;
-import org.apache.doris.analysis.IsNullPredicate;
-import org.apache.doris.analysis.LargeIntLiteral;
-import org.apache.doris.analysis.LikePredicate;
-import org.apache.doris.analysis.LikePredicate.Operator;
 import org.apache.doris.analysis.PartitionDesc;
 import org.apache.doris.analysis.RangePartitionDesc;
-import org.apache.doris.analysis.SlotRef;
 import org.apache.doris.catalog.ArrayType;
 import org.apache.doris.catalog.Column;
 import org.apache.doris.catalog.ScalarType;
 import org.apache.doris.catalog.Type;
 import org.apache.doris.common.AnalysisException;
 import org.apache.doris.common.DdlException;
-import org.apache.doris.external.elasticsearch.QueryBuilders.QueryBuilder;
-import org.apache.doris.thrift.TExprOpcode;
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
@@ -50,12 +33,10 @@ import org.json.simple.JSONObject;
 import org.json.simple.JSONValue;
 
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import java.util.stream.Collectors;
 
 /**
  * Util for ES, some static method.
@@ -213,167 +194,6 @@ public class EsUtil {
         return properties;
     }
 
-    private static QueryBuilder toCompoundEsDsl(Expr expr, List<Expr> 
notPushDownList,
-            Map<String, String> fieldsContext) {
-        CompoundPredicate compoundPredicate = (CompoundPredicate) expr;
-        switch (compoundPredicate.getOp()) {
-            case AND: {
-                QueryBuilder left = toEsDsl(compoundPredicate.getChild(0), 
notPushDownList, fieldsContext);
-                QueryBuilder right = toEsDsl(compoundPredicate.getChild(1), 
notPushDownList, fieldsContext);
-                if (left != null && right != null) {
-                    return QueryBuilders.boolQuery().must(left).must(right);
-                }
-                return null;
-            }
-            case OR: {
-                int beforeSize = notPushDownList.size();
-                QueryBuilder left = toEsDsl(compoundPredicate.getChild(0), 
notPushDownList, fieldsContext);
-                QueryBuilder right = toEsDsl(compoundPredicate.getChild(1), 
notPushDownList, fieldsContext);
-                int afterSize = notPushDownList.size();
-                if (left != null && right != null) {
-                    return 
QueryBuilders.boolQuery().should(left).should(right);
-                }
-                // One 'or' association cannot be pushed down and the other 
cannot be pushed down
-                if (afterSize > beforeSize) {
-                    if (left != null) {
-                        // add right if right don't pushdown
-                        notPushDownList.add(compoundPredicate.getChild(0));
-                    } else if (right != null) {
-                        // add left if left don't pushdown
-                        notPushDownList.add(compoundPredicate.getChild(1));
-                    }
-                }
-                return null;
-            }
-            case NOT: {
-                QueryBuilder child = toEsDsl(compoundPredicate.getChild(0), 
notPushDownList, fieldsContext);
-                if (child != null) {
-                    return QueryBuilders.boolQuery().mustNot(child);
-                }
-                return null;
-            }
-            default:
-                return null;
-        }
-    }
-
-    private static Expr exprWithoutCast(Expr expr) {
-        if (expr instanceof CastExpr) {
-            return exprWithoutCast(expr.getChild(0));
-        }
-        return expr;
-    }
-
-    public static QueryBuilder toEsDsl(Expr expr) {
-        return toEsDsl(expr, new ArrayList<>(), new HashMap<>());
-    }
-
-    /**
-     * Doris expr to es dsl.
-     **/
-    public static QueryBuilder toEsDsl(Expr expr, List<Expr> notPushDownList, 
Map<String, String> fieldsContext) {
-        if (expr == null) {
-            return null;
-        }
-        // CompoundPredicate, `between` also converted to CompoundPredicate.
-        if (expr instanceof CompoundPredicate) {
-            return toCompoundEsDsl(expr, notPushDownList, fieldsContext);
-        }
-        TExprOpcode opCode = expr.getOpcode();
-        String column;
-        Expr leftExpr = expr.getChild(0);
-        // Type transformed cast can not pushdown
-        if (leftExpr instanceof CastExpr) {
-            Expr withoutCastExpr = exprWithoutCast(leftExpr);
-            // pushdown col(float) >= 3
-            if (withoutCastExpr.getType().equals(leftExpr.getType()) || 
(withoutCastExpr.getType().isFloatingPointType()
-                    && leftExpr.getType().isFloatingPointType())) {
-                column = ((SlotRef) withoutCastExpr).getColumnName();
-            } else {
-                notPushDownList.add(expr);
-                return null;
-            }
-        } else if (leftExpr instanceof SlotRef) {
-            column = ((SlotRef) leftExpr).getColumnName();
-        } else {
-            notPushDownList.add(expr);
-            return null;
-        }
-        // Replace col with col.keyword if mapping exist.
-        column = fieldsContext.getOrDefault(column, column);
-        if (expr instanceof BinaryPredicate) {
-            Object value = toDorisLiteral(expr.getChild(1));
-            switch (opCode) {
-                case EQ:
-                case EQ_FOR_NULL:
-                    return QueryBuilders.termQuery(column, value);
-                case NE:
-                    return 
QueryBuilders.boolQuery().mustNot(QueryBuilders.termQuery(column, value));
-                case GE:
-                    return QueryBuilders.rangeQuery(column).gte(value);
-                case GT:
-                    return QueryBuilders.rangeQuery(column).gt(value);
-                case LE:
-                    return QueryBuilders.rangeQuery(column).lte(value);
-                case LT:
-                    return QueryBuilders.rangeQuery(column).lt(value);
-                default:
-                    return null;
-            }
-        }
-        if (expr instanceof IsNullPredicate) {
-            IsNullPredicate isNullPredicate = (IsNullPredicate) expr;
-            if (isNullPredicate.isNotNull()) {
-                return QueryBuilders.existsQuery(column);
-            }
-            return 
QueryBuilders.boolQuery().mustNot(QueryBuilders.existsQuery(column));
-        }
-        if (expr instanceof LikePredicate) {
-            LikePredicate likePredicate = (LikePredicate) expr;
-            if (likePredicate.getOp().equals(Operator.LIKE)) {
-                char[] chars = 
likePredicate.getChild(1).getStringValue().toCharArray();
-                // example of translation :
-                //      abc_123  ===> abc?123
-                //      abc%ykz  ===> abc*123
-                //      %abc123  ===> *abc123
-                //      _abc123  ===> ?abc123
-                //      \\_abc1  ===> \\_abc1
-                //      abc\\_123 ===> abc\\_123
-                //      abc\\%123 ===> abc\\%123
-                // NOTE. user must input sql like 'abc\\_123' or 'abc\\%ykz'
-                for (int i = 0; i < chars.length; i++) {
-                    if (chars[i] == '_' || chars[i] == '%') {
-                        if (i == 0) {
-                            chars[i] = (chars[i] == '_') ? '?' : '*';
-                        } else if (chars[i - 1] != '\\') {
-                            chars[i] = (chars[i] == '_') ? '?' : '*';
-                        }
-                    }
-                }
-                return QueryBuilders.wildcardQuery(column, new String(chars));
-            } else {
-                return QueryBuilders.wildcardQuery(column, 
likePredicate.getChild(1).getStringValue());
-            }
-        }
-        if (expr instanceof InPredicate) {
-            InPredicate inPredicate = (InPredicate) expr;
-            List<Object> values = 
inPredicate.getListChildren().stream().map(EsUtil::toDorisLiteral)
-                    .collect(Collectors.toList());
-            if (inPredicate.isNotIn()) {
-                return 
QueryBuilders.boolQuery().mustNot(QueryBuilders.termsQuery(column, values));
-            }
-            return QueryBuilders.termsQuery(column, values);
-        }
-        if (expr instanceof FunctionCallExpr) {
-            FunctionCallExpr functionCallExpr = (FunctionCallExpr) expr;
-            if ("esquery".equals(functionCallExpr.getFnName().getFunction())) {
-                String stringValue = 
functionCallExpr.getChild(1).getStringValue();
-                return new QueryBuilders.EsQueryBuilder(stringValue);
-            }
-        }
-        return null;
-    }
-
 
     /**
      * Generate columns from ES Cluster.
@@ -458,28 +278,5 @@ public class EsUtil {
         }
     }
 
-    private static Object toDorisLiteral(Expr expr) {
-        if (!expr.isLiteral()) {
-            return null;
-        }
-        if (expr instanceof BoolLiteral) {
-            BoolLiteral boolLiteral = (BoolLiteral) expr;
-            return boolLiteral.getValue();
-        } else if (expr instanceof DecimalLiteral) {
-            DecimalLiteral decimalLiteral = (DecimalLiteral) expr;
-            return decimalLiteral.getValue();
-        } else if (expr instanceof FloatLiteral) {
-            FloatLiteral floatLiteral = (FloatLiteral) expr;
-            return floatLiteral.getValue();
-        } else if (expr instanceof IntLiteral) {
-            IntLiteral intLiteral = (IntLiteral) expr;
-            return intLiteral.getValue();
-        } else if (expr instanceof LargeIntLiteral) {
-            LargeIntLiteral largeIntLiteral = (LargeIntLiteral) expr;
-            return largeIntLiteral.getLongValue();
-        }
-        return expr.getStringValue();
-    }
-
 }
 
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/external/elasticsearch/QueryBuilders.java
 
b/fe/fe-core/src/main/java/org/apache/doris/external/elasticsearch/QueryBuilders.java
index 3dd800cb91..cc269a452a 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/external/elasticsearch/QueryBuilders.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/external/elasticsearch/QueryBuilders.java
@@ -17,19 +17,42 @@
 
 package org.apache.doris.external.elasticsearch;
 
+import org.apache.doris.analysis.BinaryPredicate;
+import org.apache.doris.analysis.BoolLiteral;
+import org.apache.doris.analysis.CastExpr;
+import org.apache.doris.analysis.CompoundPredicate;
+import org.apache.doris.analysis.DecimalLiteral;
+import org.apache.doris.analysis.Expr;
+import org.apache.doris.analysis.FloatLiteral;
+import org.apache.doris.analysis.FunctionCallExpr;
+import org.apache.doris.analysis.InPredicate;
+import org.apache.doris.analysis.IntLiteral;
+import org.apache.doris.analysis.IsNullPredicate;
+import org.apache.doris.analysis.LargeIntLiteral;
+import org.apache.doris.analysis.LikePredicate;
+import org.apache.doris.analysis.LikePredicate.Operator;
+import org.apache.doris.analysis.SlotRef;
+import org.apache.doris.catalog.EsResource;
+import org.apache.doris.thrift.TExprOpcode;
+
 import com.fasterxml.jackson.core.JsonGenerator;
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import lombok.Builder;
+import lombok.Data;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 
 import java.io.IOException;
 import java.io.StringWriter;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Objects;
+import java.util.stream.Collectors;
 
 
 /**
@@ -38,6 +61,233 @@ import java.util.Objects;
  */
 public final class QueryBuilders {
 
+    /**
+     * Generate dsl from compound expr.
+     **/
+    private static QueryBuilder toCompoundEsDsl(Expr expr, List<Expr> 
notPushDownList,
+            Map<String, String> fieldsContext, BuilderOptions builderOptions) {
+        CompoundPredicate compoundPredicate = (CompoundPredicate) expr;
+        switch (compoundPredicate.getOp()) {
+            case AND: {
+                QueryBuilder left = toEsDsl(compoundPredicate.getChild(0), 
notPushDownList, fieldsContext,
+                        builderOptions);
+                QueryBuilder right = toEsDsl(compoundPredicate.getChild(1), 
notPushDownList, fieldsContext,
+                        builderOptions);
+                if (left != null && right != null) {
+                    return QueryBuilders.boolQuery().must(left).must(right);
+                }
+                return null;
+            }
+            case OR: {
+                int beforeSize = notPushDownList.size();
+                QueryBuilder left = toEsDsl(compoundPredicate.getChild(0), 
notPushDownList, fieldsContext,
+                        builderOptions);
+                QueryBuilder right = toEsDsl(compoundPredicate.getChild(1), 
notPushDownList, fieldsContext,
+                        builderOptions);
+                int afterSize = notPushDownList.size();
+                if (left != null && right != null) {
+                    return 
QueryBuilders.boolQuery().should(left).should(right);
+                }
+                // One 'or' association cannot be pushed down and the other 
cannot be pushed down
+                if (afterSize > beforeSize) {
+                    notPushDownList.add(compoundPredicate);
+                }
+                return null;
+            }
+            case NOT: {
+                QueryBuilder child = toEsDsl(compoundPredicate.getChild(0), 
notPushDownList, fieldsContext,
+                        builderOptions);
+                if (child != null) {
+                    return QueryBuilders.boolQuery().mustNot(child);
+                }
+                return null;
+            }
+            default:
+                return null;
+        }
+    }
+
+    /**
+     * Get the expr inside the cast.
+     **/
+    private static Expr exprWithoutCast(Expr expr) {
+        if (expr instanceof CastExpr) {
+            return exprWithoutCast(expr.getChild(0));
+        }
+        return expr;
+    }
+
+    public static QueryBuilder toEsDsl(Expr expr) {
+        return toEsDsl(expr, new ArrayList<>(), new HashMap<>(),
+                
BuilderOptions.builder().likePushDown(Boolean.parseBoolean(EsResource.LIKE_PUSH_DOWN_DEFAULT_VALUE))
+                        .build());
+    }
+
+    private static QueryBuilder parseBinaryPredicate(Expr expr, TExprOpcode 
opCode, String column) {
+        Object value = toDorisLiteral(expr.getChild(1));
+        switch (opCode) {
+            case EQ:
+            case EQ_FOR_NULL:
+                return QueryBuilders.termQuery(column, value);
+            case NE:
+                return 
QueryBuilders.boolQuery().mustNot(QueryBuilders.termQuery(column, value));
+            case GE:
+                return QueryBuilders.rangeQuery(column).gte(value);
+            case GT:
+                return QueryBuilders.rangeQuery(column).gt(value);
+            case LE:
+                return QueryBuilders.rangeQuery(column).lte(value);
+            case LT:
+                return QueryBuilders.rangeQuery(column).lt(value);
+            default:
+                return null;
+        }
+    }
+
+    private static QueryBuilder parseIsNullPredicate(Expr expr, String column) 
{
+        IsNullPredicate isNullPredicate = (IsNullPredicate) expr;
+        if (isNullPredicate.isNotNull()) {
+            return QueryBuilders.existsQuery(column);
+        }
+        return 
QueryBuilders.boolQuery().mustNot(QueryBuilders.existsQuery(column));
+    }
+
+    private static QueryBuilder parseLikePredicate(Expr expr, String column) {
+        LikePredicate likePredicate = (LikePredicate) expr;
+        if (likePredicate.getOp().equals(Operator.LIKE)) {
+            char[] chars = 
likePredicate.getChild(1).getStringValue().toCharArray();
+            // example of translation :
+            //      abc_123  ===> abc?123
+            //      abc%ykz  ===> abc*123
+            //      %abc123  ===> *abc123
+            //      _abc123  ===> ?abc123
+            //      \\_abc1  ===> \\_abc1
+            //      abc\\_123 ===> abc\\_123
+            //      abc\\%123 ===> abc\\%123
+            // NOTE. user must input sql like 'abc\\_123' or 'abc\\%ykz'
+            for (int i = 0; i < chars.length; i++) {
+                if (chars[i] == '_' || chars[i] == '%') {
+                    if (i == 0) {
+                        chars[i] = (chars[i] == '_') ? '?' : '*';
+                    } else if (chars[i - 1] != '\\') {
+                        chars[i] = (chars[i] == '_') ? '?' : '*';
+                    }
+                }
+            }
+            return QueryBuilders.wildcardQuery(column, new String(chars));
+        } else {
+            return QueryBuilders.wildcardQuery(column, 
likePredicate.getChild(1).getStringValue());
+        }
+    }
+
+    private static QueryBuilder parseInPredicate(Expr expr, String column) {
+        InPredicate inPredicate = (InPredicate) expr;
+        List<Object> values = 
inPredicate.getListChildren().stream().map(QueryBuilders::toDorisLiteral)
+                .collect(Collectors.toList());
+        if (inPredicate.isNotIn()) {
+            return 
QueryBuilders.boolQuery().mustNot(QueryBuilders.termsQuery(column, values));
+        }
+        return QueryBuilders.termsQuery(column, values);
+    }
+
+    private static QueryBuilder parseFunctionCallExpr(Expr expr) {
+        // esquery(k1, '{
+        //        "match_phrase": {
+        //           "k1": "doris on es"
+        //        }
+        //    }');
+        // The first child k1 compatible with expr syntax
+        FunctionCallExpr functionCallExpr = (FunctionCallExpr) expr;
+        if ("esquery".equals(functionCallExpr.getFnName().getFunction())) {
+            String stringValue = functionCallExpr.getChild(1).getStringValue();
+            return new QueryBuilders.EsQueryBuilder(stringValue);
+        }
+        return null;
+    }
+
+    /**
+     * Doris expr to es dsl.
+     **/
+    public static QueryBuilder toEsDsl(Expr expr, List<Expr> notPushDownList, 
Map<String, String> fieldsContext,
+            BuilderOptions builderOptions) {
+        if (expr == null) {
+            return null;
+        }
+        // CompoundPredicate, `between` also converted to CompoundPredicate.
+        if (expr instanceof CompoundPredicate) {
+            return toCompoundEsDsl(expr, notPushDownList, fieldsContext, 
builderOptions);
+        }
+        TExprOpcode opCode = expr.getOpcode();
+        String column;
+        Expr leftExpr = expr.getChild(0);
+        // Type transformed cast can not pushdown
+        if (leftExpr instanceof CastExpr) {
+            Expr withoutCastExpr = exprWithoutCast(leftExpr);
+            // pushdown col(float) >= 3
+            if (withoutCastExpr.getType().equals(leftExpr.getType()) || 
(withoutCastExpr.getType().isFloatingPointType()
+                    && leftExpr.getType().isFloatingPointType())) {
+                column = ((SlotRef) withoutCastExpr).getColumnName();
+            } else {
+                notPushDownList.add(expr);
+                return null;
+            }
+        } else if (leftExpr instanceof SlotRef) {
+            column = ((SlotRef) leftExpr).getColumnName();
+        } else {
+            notPushDownList.add(expr);
+            return null;
+        }
+        // Replace col with col.keyword if mapping exist.
+        column = fieldsContext.getOrDefault(column, column);
+        if (expr instanceof BinaryPredicate) {
+            return parseBinaryPredicate(expr, opCode, column);
+        }
+        if (expr instanceof IsNullPredicate) {
+            return parseIsNullPredicate(expr, column);
+        }
+        if (expr instanceof LikePredicate) {
+            if (!builderOptions.isLikePushDown()) {
+                notPushDownList.add(expr);
+                return null;
+            } else {
+                return parseLikePredicate(expr, column);
+            }
+        }
+        if (expr instanceof InPredicate) {
+            return parseInPredicate(expr, column);
+        }
+        if (expr instanceof FunctionCallExpr) {
+            return parseFunctionCallExpr(expr);
+        }
+        return null;
+    }
+
+    /**
+     * Expr trans to doris literal.
+     **/
+    private static Object toDorisLiteral(Expr expr) {
+        if (!expr.isLiteral()) {
+            return null;
+        }
+        if (expr instanceof BoolLiteral) {
+            BoolLiteral boolLiteral = (BoolLiteral) expr;
+            return boolLiteral.getValue();
+        } else if (expr instanceof DecimalLiteral) {
+            DecimalLiteral decimalLiteral = (DecimalLiteral) expr;
+            return decimalLiteral.getValue();
+        } else if (expr instanceof FloatLiteral) {
+            FloatLiteral floatLiteral = (FloatLiteral) expr;
+            return floatLiteral.getValue();
+        } else if (expr instanceof IntLiteral) {
+            IntLiteral intLiteral = (IntLiteral) expr;
+            return intLiteral.getValue();
+        } else if (expr instanceof LargeIntLiteral) {
+            LargeIntLiteral largeIntLiteral = (LargeIntLiteral) expr;
+            return largeIntLiteral.getLongValue();
+        }
+        return expr.getStringValue();
+    }
+
     /**
      * A query that matches on all documents.
      */
@@ -48,7 +298,7 @@ public final class QueryBuilders {
     /**
      * A Query that matches documents containing a term.
      *
-     * @param name  The name of the field
+     * @param name The name of the field
      * @param value The value of the term
      */
     public static TermQueryBuilder termQuery(String name, String value) {
@@ -58,7 +308,7 @@ public final class QueryBuilders {
     /**
      * A Query that matches documents containing a term.
      *
-     * @param name  The name of the field
+     * @param name The name of the field
      * @param value The value of the term
      */
     public static TermQueryBuilder termQuery(String name, int value) {
@@ -68,7 +318,7 @@ public final class QueryBuilders {
     /**
      * A Query that matches documents containing a term.
      *
-     * @param name  The name of the field
+     * @param name The name of the field
      * @param value The value of the term
      */
     public static TermQueryBuilder termQuery(String name, long value) {
@@ -78,7 +328,7 @@ public final class QueryBuilders {
     /**
      * A Query that matches documents containing a term.
      *
-     * @param name  The name of the field
+     * @param name The name of the field
      * @param value The value of the term
      */
     public static TermQueryBuilder termQuery(String name, float value) {
@@ -88,7 +338,7 @@ public final class QueryBuilders {
     /**
      * A Query that matches documents containing a term.
      *
-     * @param name  The name of the field
+     * @param name The name of the field
      * @param value The value of the term
      */
     public static TermQueryBuilder termQuery(String name, double value) {
@@ -98,7 +348,7 @@ public final class QueryBuilders {
     /**
      * A Query that matches documents containing a term.
      *
-     * @param name  The name of the field
+     * @param name The name of the field
      * @param value The value of the term
      */
     public static TermQueryBuilder termQuery(String name, boolean value) {
@@ -108,7 +358,7 @@ public final class QueryBuilders {
     /**
      * A Query that matches documents containing a term.
      *
-     * @param name  The name of the field
+     * @param name The name of the field
      * @param value The value of the term
      */
     public static TermQueryBuilder termQuery(String name, Object value) {
@@ -123,7 +373,7 @@ public final class QueryBuilders {
      * a Wildcard term should not start with one of the wildcards {@code *} or
      * {@code ?}.
      *
-     * @param name  The field name
+     * @param name The field name
      * @param query The wildcard query string
      */
     public static WildcardQueryBuilder wildcardQuery(String name, String 
query) {
@@ -141,7 +391,7 @@ public final class QueryBuilders {
     /**
      * A filter for a field based on several terms matching on any of them.
      *
-     * @param name   The field name
+     * @param name The field name
      * @param values The terms
      */
     public static TermsQueryBuilder termsQuery(String name, Iterable<?> 
values) {
@@ -166,6 +416,16 @@ public final class QueryBuilders {
         return new RangeQueryBuilder(name);
     }
 
+    /**
+     * Used to pass some parameters to generate the dsl
+     **/
+    @Builder
+    @Data
+    public static class BuilderOptions {
+
+        private boolean likePushDown;
+    }
+
 
     /**
      * Base class to build various ES queries
@@ -505,7 +765,7 @@ public final class QueryBuilders {
     /**
      * Write (scalar) value (string, number, boolean or null) to json format
      *
-     * @param out   source target
+     * @param out source target
      * @param value value to write
      * @throws IOException if error
      */
diff --git a/fe/fe-core/src/main/java/org/apache/doris/planner/EsScanNode.java 
b/fe/fe-core/src/main/java/org/apache/doris/planner/EsScanNode.java
index 5a6667eb71..7c9aae4a8d 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/planner/EsScanNode.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/planner/EsScanNode.java
@@ -33,9 +33,9 @@ import org.apache.doris.common.UserException;
 import org.apache.doris.external.elasticsearch.EsShardPartitions;
 import org.apache.doris.external.elasticsearch.EsShardRouting;
 import org.apache.doris.external.elasticsearch.EsTablePartitions;
-import org.apache.doris.external.elasticsearch.EsUtil;
 import org.apache.doris.external.elasticsearch.QueryBuilders;
 import org.apache.doris.external.elasticsearch.QueryBuilders.BoolQueryBuilder;
+import org.apache.doris.external.elasticsearch.QueryBuilders.BuilderOptions;
 import org.apache.doris.external.elasticsearch.QueryBuilders.QueryBuilder;
 import org.apache.doris.statistics.StatisticalType;
 import org.apache.doris.system.Backend;
@@ -362,7 +362,8 @@ public class EsScanNode extends ScanNode {
             BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
             List<Expr> notPushDownList = new ArrayList<>();
             for (Expr expr : conjuncts) {
-                QueryBuilder queryBuilder = EsUtil.toEsDsl(expr, 
notPushDownList, fieldsContext);
+                QueryBuilder queryBuilder = QueryBuilders.toEsDsl(expr, 
notPushDownList, fieldsContext,
+                        
BuilderOptions.builder().likePushDown(table.isLikePushDown()).build());
                 if (queryBuilder != null) {
                     hasFilter = true;
                     boolQueryBuilder.must(queryBuilder);
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/external/elasticsearch/EsUtilTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/external/elasticsearch/EsUtilTest.java
index 7783b4d437..a744b0fba0 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/external/elasticsearch/EsUtilTest.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/external/elasticsearch/EsUtilTest.java
@@ -31,10 +31,12 @@ import org.apache.doris.analysis.LikePredicate;
 import org.apache.doris.analysis.SlotRef;
 import org.apache.doris.analysis.StringLiteral;
 import org.apache.doris.catalog.Column;
+import org.apache.doris.catalog.EsResource;
 import org.apache.doris.catalog.EsTable;
 import org.apache.doris.catalog.PrimitiveType;
 import org.apache.doris.catalog.Type;
 import org.apache.doris.common.ExceptionChecker;
+import org.apache.doris.external.elasticsearch.QueryBuilders.BuilderOptions;
 
 import mockit.Expectations;
 import mockit.Injectable;
@@ -179,13 +181,14 @@ public class EsUtilTest extends EsTestCase {
         Expr ltExpr = new BinaryPredicate(Operator.LT, k1, intLiteral);
         Expr gtExpr = new BinaryPredicate(Operator.GT, k1, intLiteral);
         Expr efnExpr = new BinaryPredicate(Operator.EQ_FOR_NULL, new 
SlotRef(null, "k1"), new IntLiteral(3));
-        Assertions.assertEquals("{\"term\":{\"k1\":3}}", 
EsUtil.toEsDsl(eqExpr).toJson());
-        
Assertions.assertEquals("{\"bool\":{\"must_not\":{\"term\":{\"k1\":3}}}}", 
EsUtil.toEsDsl(neExpr).toJson());
-        Assertions.assertEquals("{\"range\":{\"k1\":{\"lte\":3}}}", 
EsUtil.toEsDsl(leExpr).toJson());
-        Assertions.assertEquals("{\"range\":{\"k1\":{\"gte\":3}}}", 
EsUtil.toEsDsl(geExpr).toJson());
-        Assertions.assertEquals("{\"range\":{\"k1\":{\"lt\":3}}}", 
EsUtil.toEsDsl(ltExpr).toJson());
-        Assertions.assertEquals("{\"range\":{\"k1\":{\"gt\":3}}}", 
EsUtil.toEsDsl(gtExpr).toJson());
-        Assertions.assertEquals("{\"term\":{\"k1\":3}}", 
EsUtil.toEsDsl(efnExpr).toJson());
+        Assertions.assertEquals("{\"term\":{\"k1\":3}}", 
QueryBuilders.toEsDsl(eqExpr).toJson());
+        
Assertions.assertEquals("{\"bool\":{\"must_not\":{\"term\":{\"k1\":3}}}}",
+                QueryBuilders.toEsDsl(neExpr).toJson());
+        Assertions.assertEquals("{\"range\":{\"k1\":{\"lte\":3}}}", 
QueryBuilders.toEsDsl(leExpr).toJson());
+        Assertions.assertEquals("{\"range\":{\"k1\":{\"gte\":3}}}", 
QueryBuilders.toEsDsl(geExpr).toJson());
+        Assertions.assertEquals("{\"range\":{\"k1\":{\"lt\":3}}}", 
QueryBuilders.toEsDsl(ltExpr).toJson());
+        Assertions.assertEquals("{\"range\":{\"k1\":{\"gt\":3}}}", 
QueryBuilders.toEsDsl(gtExpr).toJson());
+        Assertions.assertEquals("{\"term\":{\"k1\":3}}", 
QueryBuilders.toEsDsl(efnExpr).toJson());
     }
 
     @Test
@@ -202,11 +205,11 @@ public class EsUtilTest extends EsTestCase {
                 binaryPredicate2);
         CompoundPredicate notPredicate = new 
CompoundPredicate(CompoundPredicate.Operator.NOT, binaryPredicate1, null);
         
Assertions.assertEquals("{\"bool\":{\"must\":[{\"term\":{\"k1\":3}},{\"range\":{\"k2\":{\"gt\":5}}}]}}",
-                EsUtil.toEsDsl(andPredicate).toJson());
+                QueryBuilders.toEsDsl(andPredicate).toJson());
         
Assertions.assertEquals("{\"bool\":{\"should\":[{\"term\":{\"k1\":3}},{\"range\":{\"k2\":{\"gt\":5}}}]}}",
-                EsUtil.toEsDsl(orPredicate).toJson());
+                QueryBuilders.toEsDsl(orPredicate).toJson());
         
Assertions.assertEquals("{\"bool\":{\"must_not\":{\"term\":{\"k1\":3}}}}",
-                EsUtil.toEsDsl(notPredicate).toJson());
+                QueryBuilders.toEsDsl(notPredicate).toJson());
     }
 
     @Test
@@ -215,8 +218,8 @@ public class EsUtilTest extends EsTestCase {
         IsNullPredicate isNullPredicate = new IsNullPredicate(k1, false);
         IsNullPredicate isNotNullPredicate = new IsNullPredicate(k1, true);
         
Assertions.assertEquals("{\"bool\":{\"must_not\":{\"exists\":{\"field\":\"k1\"}}}}",
-                EsUtil.toEsDsl(isNullPredicate).toJson());
-        Assertions.assertEquals("{\"exists\":{\"field\":\"k1\"}}", 
EsUtil.toEsDsl(isNotNullPredicate).toJson());
+                QueryBuilders.toEsDsl(isNullPredicate).toJson());
+        Assertions.assertEquals("{\"exists\":{\"field\":\"k1\"}}", 
QueryBuilders.toEsDsl(isNotNullPredicate).toJson());
     }
 
     @Test
@@ -228,9 +231,12 @@ public class EsUtilTest extends EsTestCase {
         LikePredicate likePredicate1 = new 
LikePredicate(LikePredicate.Operator.LIKE, k1, stringLiteral1);
         LikePredicate regexPredicate = new 
LikePredicate(LikePredicate.Operator.REGEXP, k1, stringLiteral2);
         LikePredicate likePredicate2 = new 
LikePredicate(LikePredicate.Operator.LIKE, k1, stringLiteral3);
-        Assertions.assertEquals("{\"wildcard\":{\"k1\":\"*1*\"}}", 
EsUtil.toEsDsl(likePredicate1).toJson());
-        Assertions.assertEquals("{\"wildcard\":{\"k1\":\"*1*\"}}", 
EsUtil.toEsDsl(regexPredicate).toJson());
-        Assertions.assertEquals("{\"wildcard\":{\"k1\":\"1?2\"}}", 
EsUtil.toEsDsl(likePredicate2).toJson());
+        Assertions.assertEquals("{\"wildcard\":{\"k1\":\"*1*\"}}", 
QueryBuilders.toEsDsl(likePredicate1).toJson());
+        Assertions.assertEquals("{\"wildcard\":{\"k1\":\"*1*\"}}", 
QueryBuilders.toEsDsl(regexPredicate).toJson());
+        Assertions.assertEquals("{\"wildcard\":{\"k1\":\"1?2\"}}", 
QueryBuilders.toEsDsl(likePredicate2).toJson());
+        List<Expr> notPushDownList = new ArrayList<>();
+        Assertions.assertNull(QueryBuilders.toEsDsl(likePredicate2, 
notPushDownList, new HashMap<>(), 
BuilderOptions.builder().likePushDown(false).build()));
+        Assertions.assertFalse(notPushDownList.isEmpty());
     }
 
     @Test
@@ -243,9 +249,9 @@ public class EsUtilTest extends EsTestCase {
         intLiterals.add(intLiteral2);
         InPredicate isInPredicate = new InPredicate(k1, intLiterals, false);
         InPredicate isNotInPredicate = new InPredicate(k1, intLiterals, true);
-        Assertions.assertEquals("{\"terms\":{\"k1\":[3,5]}}", 
EsUtil.toEsDsl(isInPredicate).toJson());
+        Assertions.assertEquals("{\"terms\":{\"k1\":[3,5]}}", 
QueryBuilders.toEsDsl(isInPredicate).toJson());
         
Assertions.assertEquals("{\"bool\":{\"must_not\":{\"terms\":{\"k1\":[3,5]}}}}",
-                EsUtil.toEsDsl(isNotInPredicate).toJson());
+                QueryBuilders.toEsDsl(isNotInPredicate).toJson());
     }
 
     @Test
@@ -257,7 +263,7 @@ public class EsUtilTest extends EsTestCase {
         exprs.add(k1);
         exprs.add(stringLiteral);
         FunctionCallExpr functionCallExpr = new FunctionCallExpr("esquery", 
exprs);
-        Assertions.assertEquals(str, 
EsUtil.toEsDsl(functionCallExpr).toJson());
+        Assertions.assertEquals(str, 
QueryBuilders.toEsDsl(functionCallExpr).toJson());
 
         SlotRef k2 = new SlotRef(null, "k2");
         IntLiteral intLiteral = new IntLiteral(5);
@@ -266,7 +272,7 @@ public class EsUtilTest extends EsTestCase {
                 functionCallExpr);
         Assertions.assertEquals(
                 
"{\"bool\":{\"must\":[{\"term\":{\"k2\":5}},{\"bool\":{\"must_not\":{\"terms\":{\"k1\":[3,5]}}}}]}}",
-                EsUtil.toEsDsl(compoundPredicate).toJson());
+                QueryBuilders.toEsDsl(compoundPredicate).toJson());
     }
 
     @Test
@@ -276,7 +282,9 @@ public class EsUtilTest extends EsTestCase {
         BinaryPredicate castPredicate = new BinaryPredicate(Operator.EQ, 
castExpr, new IntLiteral(3));
         List<Expr> notPushDownList = new ArrayList<>();
         Map<String, String> fieldsContext = new HashMap<>();
-        Assertions.assertNull(EsUtil.toEsDsl(castPredicate, notPushDownList, 
fieldsContext));
+        BuilderOptions builderOptions = BuilderOptions.builder()
+                
.likePushDown(Boolean.parseBoolean(EsResource.LIKE_PUSH_DOWN_DEFAULT_VALUE)).build();
+        Assertions.assertNull(QueryBuilders.toEsDsl(castPredicate, 
notPushDownList, fieldsContext, builderOptions));
         Assertions.assertEquals(1, notPushDownList.size());
 
         SlotRef k2 = new SlotRef(null, "k2");
@@ -284,7 +292,8 @@ public class EsUtilTest extends EsTestCase {
         BinaryPredicate eqPredicate = new BinaryPredicate(Operator.EQ, k2, 
intLiteral);
         CompoundPredicate compoundPredicate = new 
CompoundPredicate(CompoundPredicate.Operator.OR, castPredicate,
                 eqPredicate);
-        EsUtil.toEsDsl(compoundPredicate, notPushDownList, fieldsContext);
+
+        QueryBuilders.toEsDsl(compoundPredicate, notPushDownList, 
fieldsContext, builderOptions);
         Assertions.assertEquals(3, notPushDownList.size());
 
         SlotRef k3 = new SlotRef(null, "k3");
@@ -292,7 +301,7 @@ public class EsUtilTest extends EsTestCase {
         CastExpr castDoubleExpr = new CastExpr(Type.DOUBLE, k3);
         BinaryPredicate castDoublePredicate = new BinaryPredicate(Operator.GE, 
castDoubleExpr,
                 new FloatLiteral(3.0, Type.DOUBLE));
-        EsUtil.toEsDsl(castDoublePredicate, notPushDownList, fieldsContext);
+        QueryBuilders.toEsDsl(castDoublePredicate, notPushDownList, 
fieldsContext, builderOptions);
         Assertions.assertEquals(3, notPushDownList.size());
     }
 
@@ -317,22 +326,20 @@ public class EsUtilTest extends EsTestCase {
                 + 
"\"fields\":{\"keyword\":{\"ignore_above\":256,\"type\":\"keyword\"}}},"
                 + 
"\"test3\":{\"type\":\"double\"},\"test1\":{\"type\":\"keyword\"}}", 
testIndex.toJSONString());
 
-        JSONObject testDynamicTemplates = EsUtil.getMappingProps("test", 
loadJsonFromFile("data/es/es6_dynamic_templates_mapping.json"),
-                "doc");
+        JSONObject testDynamicTemplates = EsUtil.getMappingProps("test",
+                
loadJsonFromFile("data/es/es6_dynamic_templates_mapping.json"), "doc");
         
Assertions.assertEquals("{\"test4\":{\"type\":\"date\"},\"test2\":{\"type\":\"text\","
-                + 
"\"fields\":{\"keyword\":{\"ignore_above\":256,\"type\":\"keyword\"}}},"
-                + 
"\"test3\":{\"type\":\"double\"},\"test1\":{\"type\":\"keyword\"}}",
+                        + 
"\"fields\":{\"keyword\":{\"ignore_above\":256,\"type\":\"keyword\"}}},"
+                        + 
"\"test3\":{\"type\":\"double\"},\"test1\":{\"type\":\"keyword\"}}",
                 testDynamicTemplates.toJSONString());
 
         expectedEx.expect(DorisEsException.class);
         expectedEx.expectMessage("Do not support index without explicit 
mapping.");
-        EsUtil.getMappingProps("test", 
loadJsonFromFile("data/es/es6_only_dynamic_templates_mapping.json"),
-                "doc");
+        EsUtil.getMappingProps("test", 
loadJsonFromFile("data/es/es6_only_dynamic_templates_mapping.json"), "doc");
 
         expectedEx.expect(DorisEsException.class);
         expectedEx.expectMessage("Do not support index without explicit 
mapping.");
-        EsUtil.getMappingProps("test", 
loadJsonFromFile("data/es/es6_only_dynamic_templates_mapping.json"),
-                null);
+        EsUtil.getMappingProps("test", 
loadJsonFromFile("data/es/es6_only_dynamic_templates_mapping.json"), null);
     }
 
     @Test
@@ -356,17 +363,16 @@ public class EsUtilTest extends EsTestCase {
                 + 
"\"fields\":{\"keyword\":{\"ignore_above\":256,\"type\":\"keyword\"}}},"
                 + 
"\"test3\":{\"type\":\"double\"},\"test1\":{\"type\":\"keyword\"}}", 
testIndex.toJSONString());
 
-        JSONObject testDynamicTemplates = EsUtil.getMappingProps("test", 
loadJsonFromFile("data/es/es7_dynamic_templates_mapping.json"),
-                null);
+        JSONObject testDynamicTemplates = EsUtil.getMappingProps("test",
+                
loadJsonFromFile("data/es/es7_dynamic_templates_mapping.json"), null);
         
Assertions.assertEquals("{\"test4\":{\"type\":\"date\"},\"test2\":{\"type\":\"text\","
-                + 
"\"fields\":{\"keyword\":{\"ignore_above\":256,\"type\":\"keyword\"}}},"
-                + 
"\"test3\":{\"type\":\"double\"},\"test1\":{\"type\":\"keyword\"}}",
+                        + 
"\"fields\":{\"keyword\":{\"ignore_above\":256,\"type\":\"keyword\"}}},"
+                        + 
"\"test3\":{\"type\":\"double\"},\"test1\":{\"type\":\"keyword\"}}",
                 testDynamicTemplates.toJSONString());
 
         expectedEx.expect(DorisEsException.class);
         expectedEx.expectMessage("Do not support index without explicit 
mapping.");
-        EsUtil.getMappingProps("test", 
loadJsonFromFile("data/es/es7_only_dynamic_templates_mapping.json"),
-                null);
+        EsUtil.getMappingProps("test", 
loadJsonFromFile("data/es/es7_only_dynamic_templates_mapping.json"), null);
     }
 
     @Test
@@ -390,17 +396,16 @@ public class EsUtilTest extends EsTestCase {
                 + 
"\"fields\":{\"keyword\":{\"ignore_above\":256,\"type\":\"keyword\"}}},"
                 + 
"\"test3\":{\"type\":\"double\"},\"test1\":{\"type\":\"keyword\"}}", 
testIndex.toJSONString());
 
-        JSONObject testDynamicTemplates = EsUtil.getMappingProps("test", 
loadJsonFromFile("data/es/es8_dynamic_templates_mapping.json"),
-                "doc");
+        JSONObject testDynamicTemplates = EsUtil.getMappingProps("test",
+                
loadJsonFromFile("data/es/es8_dynamic_templates_mapping.json"), "doc");
         
Assertions.assertEquals("{\"test4\":{\"type\":\"date\"},\"test2\":{\"type\":\"text\","
-                + 
"\"fields\":{\"keyword\":{\"ignore_above\":256,\"type\":\"keyword\"}}},"
-                + 
"\"test3\":{\"type\":\"double\"},\"test1\":{\"type\":\"keyword\"}}",
+                        + 
"\"fields\":{\"keyword\":{\"ignore_above\":256,\"type\":\"keyword\"}}},"
+                        + 
"\"test3\":{\"type\":\"double\"},\"test1\":{\"type\":\"keyword\"}}",
                 testDynamicTemplates.toJSONString());
 
         expectedEx.expect(DorisEsException.class);
         expectedEx.expectMessage("Do not support index without explicit 
mapping.");
-        EsUtil.getMappingProps("test", 
loadJsonFromFile("data/es/es8_only_dynamic_templates_mapping.json"),
-                "doc");
+        EsUtil.getMappingProps("test", 
loadJsonFromFile("data/es/es8_only_dynamic_templates_mapping.json"), "doc");
     }
 
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to