You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@doris.apache.org by ka...@apache.org on 2020/06/09 08:45:28 UTC
[incubator-doris] branch master updated: [Doris On ES] [1/3] Add ES
QueryBuilders for debug mode (#3774)
This is an automated email from the ASF dual-hosted git repository.
kangkaisen pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-doris.git
The following commit(s) were added to refs/heads/master by this push:
new acd7a58 [Doris On ES] [1/3] Add ES QueryBuilders for debug mode (#3774)
acd7a58 is described below
commit acd7a5887588a7b438dbb478ececad99a08682b0
Author: Yunfeng,Wu <wu...@baidu.com>
AuthorDate: Tue Jun 9 16:45:16 2020 +0800
[Doris On ES] [1/3] Add ES QueryBuilders for debug mode (#3774)
---
.../org/apache/doris/analysis/CreateTableStmt.java | 2 +-
.../java/org/apache/doris/catalog/Catalog.java | 2 +-
.../java/org/apache/doris/catalog/EsTable.java | 7 +-
.../doris/common/proc/EsPartitionsProcDir.java | 2 +-
.../apache/doris/common/proc/EsShardProcDir.java | 4 +-
.../external/{ => elasticsearch}/EsIndexState.java | 2 +-
.../{ => elasticsearch}/EsMajorVersion.java | 2 +-
.../external/{ => elasticsearch}/EsNodeInfo.java | 2 +-
.../external/{ => elasticsearch}/EsRestClient.java | 18 +-
.../{ => elasticsearch}/EsShardRouting.java | 2 +-
.../external/{ => elasticsearch}/EsStateStore.java | 10 +-
.../external/{ => elasticsearch}/EsTableState.java | 2 +-
.../doris/external/{ => elasticsearch}/EsUtil.java | 2 +-
.../ExternalDataSourceException.java | 2 +-
.../external/elasticsearch/QueryBuilders.java | 459 +++++++++++++++++++++
.../java/org/apache/doris/planner/EsScanNode.java | 6 +-
.../java/org/apache/doris/es/EsStateStoreTest.java | 254 ------------
.../{es => external/elasticsearch}/EsUtilTest.java | 4 +-
.../external/elasticsearch/QueryBuildersTest.java | 173 ++++++++
19 files changed, 670 insertions(+), 285 deletions(-)
diff --git a/fe/src/main/java/org/apache/doris/analysis/CreateTableStmt.java b/fe/src/main/java/org/apache/doris/analysis/CreateTableStmt.java
index 7a87055..27d10e1 100644
--- a/fe/src/main/java/org/apache/doris/analysis/CreateTableStmt.java
+++ b/fe/src/main/java/org/apache/doris/analysis/CreateTableStmt.java
@@ -33,7 +33,7 @@ import org.apache.doris.common.FeConstants;
import org.apache.doris.common.FeNameFormat;
import org.apache.doris.common.UserException;
import org.apache.doris.common.util.PrintableMap;
-import org.apache.doris.external.EsUtil;
+import org.apache.doris.external.elasticsearch.EsUtil;
import org.apache.doris.mysql.privilege.PrivPredicate;
import org.apache.doris.qe.ConnectContext;
diff --git a/fe/src/main/java/org/apache/doris/catalog/Catalog.java b/fe/src/main/java/org/apache/doris/catalog/Catalog.java
index 43fc47f..37b70c5 100755
--- a/fe/src/main/java/org/apache/doris/catalog/Catalog.java
+++ b/fe/src/main/java/org/apache/doris/catalog/Catalog.java
@@ -127,7 +127,7 @@ import org.apache.doris.deploy.DeployManager;
import org.apache.doris.deploy.impl.AmbariDeployManager;
import org.apache.doris.deploy.impl.K8sDeployManager;
import org.apache.doris.deploy.impl.LocalFileDeployManager;
-import org.apache.doris.external.EsStateStore;
+import org.apache.doris.external.elasticsearch.EsStateStore;
import org.apache.doris.ha.BDBHA;
import org.apache.doris.ha.FrontendNodeType;
import org.apache.doris.ha.HAProtocol;
diff --git a/fe/src/main/java/org/apache/doris/catalog/EsTable.java b/fe/src/main/java/org/apache/doris/catalog/EsTable.java
index a8baaa0..c7d5e57 100644
--- a/fe/src/main/java/org/apache/doris/catalog/EsTable.java
+++ b/fe/src/main/java/org/apache/doris/catalog/EsTable.java
@@ -20,14 +20,17 @@ package org.apache.doris.catalog;
import org.apache.doris.common.DdlException;
import org.apache.doris.common.FeMetaVersion;
import org.apache.doris.common.io.Text;
-import org.apache.doris.external.EsMajorVersion;
-import org.apache.doris.external.EsTableState;
+import org.apache.doris.external.elasticsearch.EsMajorVersion;
+import org.apache.doris.external.elasticsearch.EsTableState;
import org.apache.doris.thrift.TEsTable;
import org.apache.doris.thrift.TTableDescriptor;
import org.apache.doris.thrift.TTableType;
+
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
+
import com.google.common.base.Strings;
+
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
diff --git a/fe/src/main/java/org/apache/doris/common/proc/EsPartitionsProcDir.java b/fe/src/main/java/org/apache/doris/common/proc/EsPartitionsProcDir.java
index 7d9359f..896201e 100644
--- a/fe/src/main/java/org/apache/doris/common/proc/EsPartitionsProcDir.java
+++ b/fe/src/main/java/org/apache/doris/common/proc/EsPartitionsProcDir.java
@@ -24,7 +24,7 @@ import org.apache.doris.catalog.PartitionType;
import org.apache.doris.catalog.RangePartitionInfo;
import org.apache.doris.catalog.Table.TableType;
import org.apache.doris.common.AnalysisException;
-import org.apache.doris.external.EsIndexState;
+import org.apache.doris.external.elasticsearch.EsIndexState;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
diff --git a/fe/src/main/java/org/apache/doris/common/proc/EsShardProcDir.java b/fe/src/main/java/org/apache/doris/common/proc/EsShardProcDir.java
index 51574a2..4cba64e 100644
--- a/fe/src/main/java/org/apache/doris/common/proc/EsShardProcDir.java
+++ b/fe/src/main/java/org/apache/doris/common/proc/EsShardProcDir.java
@@ -25,8 +25,8 @@ import org.apache.doris.catalog.Database;
import org.apache.doris.catalog.EsTable;
import org.apache.doris.common.AnalysisException;
import org.apache.doris.common.util.ListComparator;
-import org.apache.doris.external.EsIndexState;
-import org.apache.doris.external.EsShardRouting;
+import org.apache.doris.external.elasticsearch.EsIndexState;
+import org.apache.doris.external.elasticsearch.EsShardRouting;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
diff --git a/fe/src/main/java/org/apache/doris/external/EsIndexState.java b/fe/src/main/java/org/apache/doris/external/elasticsearch/EsIndexState.java
similarity index 99%
rename from fe/src/main/java/org/apache/doris/external/EsIndexState.java
rename to fe/src/main/java/org/apache/doris/external/elasticsearch/EsIndexState.java
index 5dca5db..d2d0e90 100644
--- a/fe/src/main/java/org/apache/doris/external/EsIndexState.java
+++ b/fe/src/main/java/org/apache/doris/external/elasticsearch/EsIndexState.java
@@ -15,7 +15,7 @@
// specific language governing permissions and limitations
// under the License.
-package org.apache.doris.external;
+package org.apache.doris.external.elasticsearch;
import org.apache.doris.analysis.PartitionKeyDesc;
import org.apache.doris.analysis.PartitionValue;
diff --git a/fe/src/main/java/org/apache/doris/external/EsMajorVersion.java b/fe/src/main/java/org/apache/doris/external/elasticsearch/EsMajorVersion.java
similarity index 98%
rename from fe/src/main/java/org/apache/doris/external/EsMajorVersion.java
rename to fe/src/main/java/org/apache/doris/external/elasticsearch/EsMajorVersion.java
index b71db8a..2319f58 100644
--- a/fe/src/main/java/org/apache/doris/external/EsMajorVersion.java
+++ b/fe/src/main/java/org/apache/doris/external/elasticsearch/EsMajorVersion.java
@@ -15,7 +15,7 @@
// specific language governing permissions and limitations
// under the License.
-package org.apache.doris.external;
+package org.apache.doris.external.elasticsearch;
/**
diff --git a/fe/src/main/java/org/apache/doris/external/EsNodeInfo.java b/fe/src/main/java/org/apache/doris/external/elasticsearch/EsNodeInfo.java
similarity index 99%
rename from fe/src/main/java/org/apache/doris/external/EsNodeInfo.java
rename to fe/src/main/java/org/apache/doris/external/elasticsearch/EsNodeInfo.java
index 61b513b..4e11f9d 100644
--- a/fe/src/main/java/org/apache/doris/external/EsNodeInfo.java
+++ b/fe/src/main/java/org/apache/doris/external/elasticsearch/EsNodeInfo.java
@@ -15,7 +15,7 @@
// specific language governing permissions and limitations
// under the License.
-package org.apache.doris.external;
+package org.apache.doris.external.elasticsearch;
import org.apache.doris.thrift.TNetworkAddress;
diff --git a/fe/src/main/java/org/apache/doris/external/EsRestClient.java b/fe/src/main/java/org/apache/doris/external/elasticsearch/EsRestClient.java
similarity index 95%
rename from fe/src/main/java/org/apache/doris/external/EsRestClient.java
rename to fe/src/main/java/org/apache/doris/external/elasticsearch/EsRestClient.java
index 2b93ea9..83cbc0c 100644
--- a/fe/src/main/java/org/apache/doris/external/EsRestClient.java
+++ b/fe/src/main/java/org/apache/doris/external/elasticsearch/EsRestClient.java
@@ -15,12 +15,8 @@
// specific language governing permissions and limitations
// under the License.
-package org.apache.doris.external;
+package org.apache.doris.external.elasticsearch;
-import okhttp3.Credentials;
-import okhttp3.OkHttpClient;
-import okhttp3.Request;
-import okhttp3.Response;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.util.Strings;
@@ -35,6 +31,11 @@ import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
+import okhttp3.Credentials;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.Response;
+
public class EsRestClient {
private static final Logger LOG = LogManager.getLogger(EsRestClient.class);
private ObjectMapper mapper;
@@ -142,14 +143,19 @@ public class EsRestClient {
Request request = builder.get()
.url(currentNode + "/" + path)
.build();
+ Response response = null;
try {
- Response response = networkClient.newCall(request).execute();
+ response = networkClient.newCall(request).execute();
if (response.isSuccessful()) {
return response.body().string();
}
} catch (IOException e) {
LOG.warn("request node [{}] [{}] failures {}, try next nodes", currentNode, path, e);
scratchExceptionForThrow = e;
+ } finally {
+ if (response != null) {
+ response.close();
+ }
}
nextNode = selectNextNode();
if (!nextNode) {
diff --git a/fe/src/main/java/org/apache/doris/external/EsShardRouting.java b/fe/src/main/java/org/apache/doris/external/elasticsearch/EsShardRouting.java
similarity index 98%
rename from fe/src/main/java/org/apache/doris/external/EsShardRouting.java
rename to fe/src/main/java/org/apache/doris/external/elasticsearch/EsShardRouting.java
index 12afa5f..c4474ae 100644
--- a/fe/src/main/java/org/apache/doris/external/EsShardRouting.java
+++ b/fe/src/main/java/org/apache/doris/external/elasticsearch/EsShardRouting.java
@@ -15,7 +15,7 @@
// specific language governing permissions and limitations
// under the License.
-package org.apache.doris.external;
+package org.apache.doris.external.elasticsearch;
import org.apache.commons.lang.StringUtils;
diff --git a/fe/src/main/java/org/apache/doris/external/EsStateStore.java b/fe/src/main/java/org/apache/doris/external/elasticsearch/EsStateStore.java
similarity index 99%
rename from fe/src/main/java/org/apache/doris/external/EsStateStore.java
rename to fe/src/main/java/org/apache/doris/external/elasticsearch/EsStateStore.java
index 460cc70..d22bb70 100644
--- a/fe/src/main/java/org/apache/doris/external/EsStateStore.java
+++ b/fe/src/main/java/org/apache/doris/external/elasticsearch/EsStateStore.java
@@ -15,7 +15,7 @@
// specific language governing permissions and limitations
// under the License.
-package org.apache.doris.external;
+package org.apache.doris.external.elasticsearch;
import org.apache.doris.catalog.Catalog;
import org.apache.doris.catalog.Column;
@@ -32,14 +32,14 @@ import org.apache.doris.common.Config;
import org.apache.doris.common.DdlException;
import org.apache.doris.common.util.MasterDaemon;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Range;
-
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.json.JSONObject;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Range;
+
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
diff --git a/fe/src/main/java/org/apache/doris/external/EsTableState.java b/fe/src/main/java/org/apache/doris/external/elasticsearch/EsTableState.java
similarity index 98%
rename from fe/src/main/java/org/apache/doris/external/EsTableState.java
rename to fe/src/main/java/org/apache/doris/external/elasticsearch/EsTableState.java
index 59b69aa..2b546a6 100644
--- a/fe/src/main/java/org/apache/doris/external/EsTableState.java
+++ b/fe/src/main/java/org/apache/doris/external/elasticsearch/EsTableState.java
@@ -15,7 +15,7 @@
// specific language governing permissions and limitations
// under the License.
-package org.apache.doris.external;
+package org.apache.doris.external.elasticsearch;
import java.util.Map;
import java.util.Random;
diff --git a/fe/src/main/java/org/apache/doris/external/EsUtil.java b/fe/src/main/java/org/apache/doris/external/elasticsearch/EsUtil.java
similarity index 98%
rename from fe/src/main/java/org/apache/doris/external/EsUtil.java
rename to fe/src/main/java/org/apache/doris/external/elasticsearch/EsUtil.java
index 4e05d0e..754f1ee 100644
--- a/fe/src/main/java/org/apache/doris/external/EsUtil.java
+++ b/fe/src/main/java/org/apache/doris/external/elasticsearch/EsUtil.java
@@ -15,7 +15,7 @@
// specific language governing permissions and limitations
// under the License.
-package org.apache.doris.external;
+package org.apache.doris.external.elasticsearch;
import org.json.JSONObject;
diff --git a/fe/src/main/java/org/apache/doris/external/ExternalDataSourceException.java b/fe/src/main/java/org/apache/doris/external/elasticsearch/ExternalDataSourceException.java
similarity index 95%
rename from fe/src/main/java/org/apache/doris/external/ExternalDataSourceException.java
rename to fe/src/main/java/org/apache/doris/external/elasticsearch/ExternalDataSourceException.java
index aee34a6..abb6744 100644
--- a/fe/src/main/java/org/apache/doris/external/ExternalDataSourceException.java
+++ b/fe/src/main/java/org/apache/doris/external/elasticsearch/ExternalDataSourceException.java
@@ -15,7 +15,7 @@
// specific language governing permissions and limitations
// under the License.
-package org.apache.doris.external;
+package org.apache.doris.external.elasticsearch;
import org.apache.doris.common.UserException;
diff --git a/fe/src/main/java/org/apache/doris/external/elasticsearch/QueryBuilders.java b/fe/src/main/java/org/apache/doris/external/elasticsearch/QueryBuilders.java
new file mode 100644
index 0000000..cf51470
--- /dev/null
+++ b/fe/src/main/java/org/apache/doris/external/elasticsearch/QueryBuilders.java
@@ -0,0 +1,459 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.external.elasticsearch;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+
+/**
+ * Utility class to generate elastic search queries.
+ * Some query builders and static helper method have been copied from Elasticsearch
+ */
+public final class QueryBuilders {
+
+ /**
+ * A query that matches on all documents.
+ */
+ public static MatchAllQueryBuilder matchAllQuery() {
+ return new MatchAllQueryBuilder();
+ }
+
+ /**
+ * A Query that matches documents containing a term.
+ *
+ * @param name The name of the field
+ * @param value The value of the term
+ */
+ public static TermQueryBuilder termQuery(String name, String value) {
+ return new TermQueryBuilder(name, value);
+ }
+
+ /**
+ * A Query that matches documents containing a term.
+ *
+ * @param name The name of the field
+ * @param value The value of the term
+ */
+ public static TermQueryBuilder termQuery(String name, int value) {
+ return new TermQueryBuilder(name, value);
+ }
+
+ /**
+ * A Query that matches documents containing a term.
+ *
+ * @param name The name of the field
+ * @param value The value of the term
+ */
+ public static TermQueryBuilder termQuery(String name, long value) {
+ return new TermQueryBuilder(name, value);
+ }
+
+ /**
+ * A Query that matches documents containing a term.
+ *
+ * @param name The name of the field
+ * @param value The value of the term
+ */
+ public static TermQueryBuilder termQuery(String name, float value) {
+ return new TermQueryBuilder(name, value);
+ }
+
+ /**
+ * A Query that matches documents containing a term.
+ *
+ * @param name The name of the field
+ * @param value The value of the term
+ */
+ public static TermQueryBuilder termQuery(String name, double value) {
+ return new TermQueryBuilder(name, value);
+ }
+
+ /**
+ * A Query that matches documents containing a term.
+ *
+ * @param name The name of the field
+ * @param value The value of the term
+ */
+ public static TermQueryBuilder termQuery(String name, boolean value) {
+ return new TermQueryBuilder(name, value);
+ }
+
+ /**
+ * A Query that matches documents containing a term.
+ *
+ * @param name The name of the field
+ * @param value The value of the term
+ */
+ public static TermQueryBuilder termQuery(String name, Object value) {
+ return new TermQueryBuilder(name, value);
+ }
+
+ /**
+ * Implements the wildcard search query. Supported wildcards are {@code *}, which
+ * matches any character sequence (including the empty one), and {@code ?},
+ * which matches any single character. Note this query can be slow, as it
+ * needs to iterate over many terms. In order to prevent extremely slow WildcardQueries,
+ * a Wildcard term should not start with one of the wildcards {@code *} or
+ * {@code ?}.
+ *
+ * @param name The field name
+ * @param query The wildcard query string
+ */
+ public static WildcardQueryBuilder wildcardQuery(String name, String query) {
+ return new WildcardQueryBuilder(name, query);
+ }
+
+ /**
+ * A Query that matches documents matching boolean combinations of other queries.
+ */
+ public static BoolQueryBuilder boolQuery() {
+ return new BoolQueryBuilder();
+ }
+
+
+ /**
+ * A filter for a field based on several terms matching on any of them.
+ *
+ * @param name The field name
+ * @param values The terms
+ */
+ public static TermsQueryBuilder termsQuery(String name, Iterable<?> values) {
+ return new TermsQueryBuilder(name, values);
+ }
+
+ /**
+ * A filter to filter only documents where a field exists in them.
+ *
+ * @param name The name of the field
+ */
+ public static ExistsQueryBuilder existsQuery(String name) {
+ return new ExistsQueryBuilder(name);
+ }
+
+ /**
+ * A Query that matches documents within an range of terms.
+ *
+ * @param name The field name
+ */
+ public static RangeQueryBuilder rangeQuery(String name) {
+ return new RangeQueryBuilder(name);
+ }
+
+
+ /**
+ * Base class to build various ES queries
+ */
+ abstract static class QueryBuilder {
+
+ /**
+ * Convert query to JSON format
+ *
+ * @param out used to generate JSON elements
+ * @throws IOException if IO error occurred
+ */
+ abstract void toJson(JsonGenerator out) throws IOException;
+ }
+
+ /**
+ * A Query that matches documents matching boolean combinations of other queries.
+ */
+ static class BoolQueryBuilder extends QueryBuilder {
+
+ private final List<QueryBuilder> mustClauses = new ArrayList<>();
+ private final List<QueryBuilder> mustNotClauses = new ArrayList<>();
+ private final List<QueryBuilder> filterClauses = new ArrayList<>();
+ private final List<QueryBuilder> shouldClauses = new ArrayList<>();
+
+ BoolQueryBuilder must(QueryBuilder queryBuilder) {
+ Objects.requireNonNull(queryBuilder);
+ mustClauses.add(queryBuilder);
+ return this;
+ }
+
+ BoolQueryBuilder filter(QueryBuilder queryBuilder) {
+ Objects.requireNonNull(queryBuilder);
+ filterClauses.add(queryBuilder);
+ return this;
+ }
+
+ BoolQueryBuilder mustNot(QueryBuilder queryBuilder) {
+ Objects.requireNonNull(queryBuilder);
+ mustNotClauses.add(queryBuilder);
+ return this;
+ }
+
+ BoolQueryBuilder should(QueryBuilder queryBuilder) {
+ Objects.requireNonNull(queryBuilder);
+ shouldClauses.add(queryBuilder);
+ return this;
+ }
+
+ @Override
+ protected void toJson(JsonGenerator out) throws IOException {
+ out.writeStartObject();
+ out.writeFieldName("bool");
+ out.writeStartObject();
+ writeJsonArray("must", mustClauses, out);
+ writeJsonArray("filter", filterClauses, out);
+ writeJsonArray("must_not", mustNotClauses, out);
+ writeJsonArray("should", shouldClauses, out);
+ out.writeEndObject();
+ out.writeEndObject();
+ }
+
+ private void writeJsonArray(String field, List<QueryBuilder> clauses, JsonGenerator out)
+ throws IOException {
+ if (clauses.isEmpty()) {
+ return;
+ }
+
+ if (clauses.size() == 1) {
+ out.writeFieldName(field);
+ clauses.get(0).toJson(out);
+ } else {
+ out.writeArrayFieldStart(field);
+ for (QueryBuilder clause : clauses) {
+ clause.toJson(out);
+ }
+ out.writeEndArray();
+ }
+ }
+ }
+
+ /**
+ * A Query that matches documents containing a term
+ */
+ static class TermQueryBuilder extends QueryBuilder {
+ private final String fieldName;
+ private final Object value;
+
+ private TermQueryBuilder(final String fieldName, final Object value) {
+ this.fieldName = Objects.requireNonNull(fieldName, "fieldName");
+ this.value = Objects.requireNonNull(value, "value");
+ }
+
+ @Override
+ void toJson(final JsonGenerator out) throws IOException {
+ out.writeStartObject();
+ out.writeFieldName("term");
+ out.writeStartObject();
+ out.writeFieldName(fieldName);
+ writeObject(out, value);
+ out.writeEndObject();
+ out.writeEndObject();
+ }
+ }
+
+ /**
+ * A filter for a field based on several terms matching on any of them.
+ */
+ static class TermsQueryBuilder extends QueryBuilder {
+ private final String fieldName;
+ private final Iterable<?> values;
+
+ private TermsQueryBuilder(final String fieldName, final Iterable<?> values) {
+ this.fieldName = Objects.requireNonNull(fieldName, "fieldName");
+ this.values = Objects.requireNonNull(values, "values");
+ }
+
+ @Override
+ void toJson(final JsonGenerator out) throws IOException {
+ out.writeStartObject();
+ out.writeFieldName("terms");
+ out.writeStartObject();
+ out.writeFieldName(fieldName);
+ out.writeStartArray();
+ for (Object value : values) {
+ writeObject(out, value);
+ }
+ out.writeEndArray();
+ out.writeEndObject();
+ out.writeEndObject();
+ }
+ }
+
+ /**
+ * A Query that matches documents within an range of terms
+ */
+ static class RangeQueryBuilder extends QueryBuilder {
+
+ private final String field;
+
+ private Object lt;
+ private boolean lte;
+ private Object gt;
+ private boolean gte;
+
+ private String format;
+
+ private RangeQueryBuilder(final String field) {
+ this.field = Objects.requireNonNull(field, "fieldName");
+ }
+
+ private RangeQueryBuilder to(Object value, boolean lte) {
+ this.lt = Objects.requireNonNull(value, "value");
+ this.lte = lte;
+ return this;
+ }
+
+ private RangeQueryBuilder from(Object value, boolean gte) {
+ this.gt = Objects.requireNonNull(value, "value");
+ this.gte = gte;
+ return this;
+ }
+
+ RangeQueryBuilder lt(Object value) {
+ return to(value, false);
+ }
+
+ RangeQueryBuilder lte(Object value) {
+ return to(value, true);
+ }
+
+ RangeQueryBuilder gt(Object value) {
+ return from(value, false);
+ }
+
+ RangeQueryBuilder gte(Object value) {
+ return from(value, true);
+ }
+
+ RangeQueryBuilder format(String format) {
+ this.format = format;
+ return this;
+ }
+
+ @Override
+ void toJson(final JsonGenerator out) throws IOException {
+ if (lt == null && gt == null) {
+ throw new IllegalStateException("Either lower or upper bound should be provided");
+ }
+
+ out.writeStartObject();
+ out.writeFieldName("range");
+ out.writeStartObject();
+ out.writeFieldName(field);
+ out.writeStartObject();
+
+ if (gt != null) {
+ final String op = gte ? "gte" : "gt";
+ out.writeFieldName(op);
+ writeObject(out, gt);
+ }
+
+ if (lt != null) {
+ final String op = lte ? "lte" : "lt";
+ out.writeFieldName(op);
+ writeObject(out, lt);
+ }
+
+ if (format != null) {
+ out.writeStringField("format", format);
+ }
+
+ out.writeEndObject();
+ out.writeEndObject();
+ out.writeEndObject();
+ }
+ }
+
+
+ /**
+ * Supported wildcards are {@code *}, which
+ * matches any character sequence (including the empty one), and {@code ?},
+ * which matches any single character
+ */
+ static class WildcardQueryBuilder extends QueryBuilder {
+
+ private final String fieldName;
+ private final String value;
+
+
+ public WildcardQueryBuilder(String fieldName, String value) {
+ this.fieldName = Objects.requireNonNull(fieldName, "fieldName");
+ this.value = Objects.requireNonNull(value, "value");
+ }
+
+ @Override
+ void toJson(JsonGenerator out) throws IOException {
+ out.writeStartObject();
+ out.writeFieldName("wildcard");
+ out.writeStartObject();
+ out.writeFieldName(fieldName);
+ out.writeString(value);
+ out.writeEndObject();
+ out.writeEndObject();
+ }
+ }
+
+ /**
+ * Query that only match on documents that the fieldName has a value in them
+ */
+ static class ExistsQueryBuilder extends QueryBuilder {
+
+ private final String fieldName;
+
+ ExistsQueryBuilder(final String fieldName) {
+ this.fieldName = Objects.requireNonNull(fieldName, "fieldName");
+ }
+
+ @Override
+ void toJson(JsonGenerator out) throws IOException {
+ out.writeStartObject();
+ out.writeFieldName("exists");
+ out.writeStartObject();
+ out.writeStringField("field", fieldName);
+ out.writeEndObject();
+ out.writeEndObject();
+
+ }
+ }
+
+ /**
+ * A query that matches on all documents
+ */
+ static class MatchAllQueryBuilder extends QueryBuilder {
+
+ private MatchAllQueryBuilder() {
+ }
+
+ @Override
+ void toJson(final JsonGenerator out) throws IOException {
+ out.writeStartObject();
+ out.writeFieldName("match_all");
+ out.writeStartObject();
+ out.writeEndObject();
+ out.writeEndObject();
+ }
+ }
+
+ /**
+ * Write (scalar) value (string, number, boolean or null) to json format
+ *
+ * @param out source target
+ * @param value value to write
+ * @throws IOException if error
+ */
+ private static void writeObject(JsonGenerator out, Object value) throws IOException {
+ out.writeObject(value);
+ }
+}
diff --git a/fe/src/main/java/org/apache/doris/planner/EsScanNode.java b/fe/src/main/java/org/apache/doris/planner/EsScanNode.java
index 65fd3f1..497fa63 100644
--- a/fe/src/main/java/org/apache/doris/planner/EsScanNode.java
+++ b/fe/src/main/java/org/apache/doris/planner/EsScanNode.java
@@ -26,9 +26,9 @@ import org.apache.doris.catalog.PartitionKey;
import org.apache.doris.catalog.RangePartitionInfo;
import org.apache.doris.common.AnalysisException;
import org.apache.doris.common.UserException;
-import org.apache.doris.external.EsIndexState;
-import org.apache.doris.external.EsShardRouting;
-import org.apache.doris.external.EsTableState;
+import org.apache.doris.external.elasticsearch.EsIndexState;
+import org.apache.doris.external.elasticsearch.EsShardRouting;
+import org.apache.doris.external.elasticsearch.EsTableState;
import org.apache.doris.system.Backend;
import org.apache.doris.thrift.TEsScanNode;
import org.apache.doris.thrift.TEsScanRange;
diff --git a/fe/src/test/java/org/apache/doris/es/EsStateStoreTest.java b/fe/src/test/java/org/apache/doris/es/EsStateStoreTest.java
deleted file mode 100644
index c41c2c4..0000000
--- a/fe/src/test/java/org/apache/doris/es/EsStateStoreTest.java
+++ /dev/null
@@ -1,254 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements. See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership. The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License. You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package org.apache.doris.es;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import org.apache.doris.analysis.PartitionValue;
-import org.apache.doris.catalog.Catalog;
-import org.apache.doris.catalog.CatalogTestUtil;
-import org.apache.doris.catalog.EsTable;
-import org.apache.doris.catalog.FakeCatalog;
-import org.apache.doris.catalog.FakeEditLog;
-import org.apache.doris.catalog.PartitionKey;
-import org.apache.doris.catalog.RangePartitionInfo;
-import org.apache.doris.common.AnalysisException;
-import org.apache.doris.common.FeMetaVersion;
-import org.apache.doris.external.EsIndexState;
-import org.apache.doris.external.EsStateStore;
-import org.apache.doris.external.EsTableState;
-import org.apache.doris.meta.MetaContext;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Range;
-
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.lang.reflect.InvocationTargetException;
-import java.net.URISyntaxException;
-import java.util.Map;
-
-public class EsStateStoreTest {
-
- private static FakeEditLog fakeEditLog;
- private static FakeCatalog fakeCatalog;
- private static Catalog masterCatalog;
- private static String clusterStateStr1 = "";
- private static String clusterStateStr2 = "";
- private static String clusterStateStr3 = "";
- private static String clusterStateStr4 = "";
- private static String clusterStateStr5 = "";
- private EsStateStore esStateStore;
-
- @BeforeClass
- public static void init() throws IOException, InstantiationException, IllegalAccessException,
- IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException,
- URISyntaxException {
- fakeEditLog = new FakeEditLog();
- fakeCatalog = new FakeCatalog();
- masterCatalog = CatalogTestUtil.createTestCatalog();
- MetaContext metaContext = new MetaContext();
- metaContext.setMetaVersion(FeMetaVersion.VERSION_40);
- metaContext.setThreadLocalInfo();
- // masterCatalog.setJournalVersion(FeMetaVersion.VERSION_40);
- FakeCatalog.setCatalog(masterCatalog);
- clusterStateStr1 = loadJsonFromFile("data/es/clusterstate1.json");
- clusterStateStr2 = loadJsonFromFile("data/es/clusterstate2.json");
- clusterStateStr3 = loadJsonFromFile("data/es/clusterstate3.json");
- clusterStateStr4 = loadJsonFromFile("data/es/clusterstate4.json");
- clusterStateStr5 = loadJsonFromFile("data/es/clusterstate5.json");
- }
-
- @Before
- public void setUp() {
- esStateStore = new EsStateStore();
- }
-
- /**
- * partitioned es table schema: k1(date), k2(int), v(double)
- * @throws AnalysisException
- */
- @Test
- public void testParsePartitionedClusterState() throws AnalysisException {
- EsTable esTable = (EsTable) Catalog.getCurrentCatalog()
- .getDb(CatalogTestUtil.testDb1)
- .getTable(CatalogTestUtil.testPartitionedEsTable1);
- boolean hasException = false;
- EsTableState esTableState = null;
- try {
- esTableState = esStateStore.getTableState(clusterStateStr1, esTable);
- } catch (Exception e) {
- e.printStackTrace();
- hasException = true;
- }
- assertFalse(hasException);
- assertNotNull(esTableState);
- assertEquals(2, esTableState.getPartitionedIndexStates().size());
- RangePartitionInfo definedPartInfo = (RangePartitionInfo) esTable.getPartitionInfo();
- RangePartitionInfo rangePartitionInfo = (RangePartitionInfo) esTableState.getPartitionInfo();
- Map<Long, Range<PartitionKey>> rangeMap = rangePartitionInfo.getIdToRange(false);
- assertEquals(2, rangeMap.size());
- Range<PartitionKey> part0 = rangeMap.get(new Long(0));
- EsIndexState esIndexState1 = esTableState.getIndexState(0);
- assertEquals(5, esIndexState1.getShardRoutings().size());
- assertEquals("index1", esIndexState1.getIndexName());
- PartitionKey lowKey = PartitionKey.createInfinityPartitionKey(definedPartInfo.getPartitionColumns(), false);
- PartitionKey upperKey = PartitionKey.createPartitionKey(Lists.newArrayList(new PartitionValue("2018-10-01")),
- definedPartInfo.getPartitionColumns());
- Range<PartitionKey> newRange = Range.closedOpen(lowKey, upperKey);
- assertEquals(newRange, part0);
- Range<PartitionKey> part1 = rangeMap.get(new Long(1));
- EsIndexState esIndexState2 = esTableState.getIndexState(1);
- assertEquals("index2", esIndexState2.getIndexName());
- lowKey = PartitionKey.createPartitionKey(Lists.newArrayList(new PartitionValue("2018-10-01")),
- definedPartInfo.getPartitionColumns());
- upperKey = PartitionKey.createPartitionKey(Lists.newArrayList(new PartitionValue("2018-10-02")),
- definedPartInfo.getPartitionColumns());
- newRange = Range.closedOpen(lowKey, upperKey);
- assertEquals(newRange, part1);
- assertEquals(6, esIndexState2.getShardRoutings().size());
- }
-
- /**
- * partitioned es table schema: k1(date), k2(int), v(double)
- * scenario desc:
- * 2 indices, one with partition desc, the other does not contains partition desc
- * @throws AnalysisException
- */
- @Test
- public void testParsePartitionedClusterStateTwoIndices() throws AnalysisException {
- EsTable esTable = (EsTable) Catalog.getCurrentCatalog()
- .getDb(CatalogTestUtil.testDb1)
- .getTable(CatalogTestUtil.testPartitionedEsTable1);
- boolean hasException = false;
- EsTableState esTableState = null;
- try {
- esTableState = esStateStore.getTableState(clusterStateStr3, esTable);
- } catch (Exception e) {
- e.printStackTrace();
- hasException = true;
- }
- assertFalse(hasException);
- assertNotNull(esTableState);
-
- // check
- assertEquals(1, esTableState.getPartitionedIndexStates().size());
- assertEquals(1, esTableState.getUnPartitionedIndexStates().size());
-
- // check partition info
- RangePartitionInfo definedPartInfo = (RangePartitionInfo) esTable.getPartitionInfo();
- RangePartitionInfo rangePartitionInfo = (RangePartitionInfo) esTableState.getPartitionInfo();
- Map<Long, Range<PartitionKey>> rangeMap = rangePartitionInfo.getIdToRange(false);
- assertEquals(1, rangeMap.size());
- Range<PartitionKey> part0 = rangeMap.get(new Long(0));
- EsIndexState esIndexState1 = esTableState.getIndexState(0);
- assertEquals(5, esIndexState1.getShardRoutings().size());
- assertEquals("index1", esIndexState1.getIndexName());
- PartitionKey lowKey = PartitionKey.createInfinityPartitionKey(definedPartInfo.getPartitionColumns(), false);
- PartitionKey upperKey = PartitionKey.createPartitionKey(Lists.newArrayList(new PartitionValue("2018-10-01")),
- definedPartInfo.getPartitionColumns());
- Range<PartitionKey> newRange = Range.closedOpen(lowKey, upperKey);
- assertEquals(newRange, part0);
-
- // check index with no partition desc
- EsIndexState esIndexState2 = esTableState.getUnPartitionedIndexStates().get("index2");
- assertEquals("index2", esIndexState2.getIndexName());
- assertEquals(6, esIndexState2.getShardRoutings().size());
- }
-
- /**
- * partitioned es table schema: k1(date), k2(int), v(double)
- * scenario desc:
- * 2 indices, both of them does not contains partition desc and es table does not have partition info
- * but cluster state have partition info
- * @throws AnalysisException
- */
- @Test
- public void testParseUnPartitionedClusterStateTwoIndices() throws AnalysisException {
- EsTable esTable = (EsTable) Catalog.getCurrentCatalog()
- .getDb(CatalogTestUtil.testDb1)
- .getTable(CatalogTestUtil.testUnPartitionedEsTableId1);
- boolean hasException = false;
- EsTableState esTableState = null;
- try {
- esTableState = esStateStore.getTableState(clusterStateStr4, esTable);
- } catch (Exception e) {
- e.printStackTrace();
- hasException = true;
- }
- assertFalse(hasException);
- assertNotNull(esTableState);
-
- // check
- assertEquals(0, esTableState.getPartitionedIndexStates().size());
- assertEquals(2, esTableState.getUnPartitionedIndexStates().size());
-
- // check index with no partition desc
- EsIndexState esIndexState1 = esTableState.getUnPartitionedIndexStates().get("index1");
- assertEquals("index1", esIndexState1.getIndexName());
- EsIndexState esIndexState2 = esTableState.getUnPartitionedIndexStates().get("index2");
- assertEquals("index2", esIndexState2.getIndexName());
- assertEquals(6, esIndexState2.getShardRoutings().size());
- }
-
-
- /**
- * partitioned es table schema: k1(date), k2(int), v(double)
- * "upperbound": "2018" is not a valid date value, so parsing procedure will fail
- */
- @Test
- public void testParseInvalidUpperbound() {
- EsTable esTable = (EsTable) Catalog.getCurrentCatalog()
- .getDb(CatalogTestUtil.testDb1)
- .getTable(CatalogTestUtil.testPartitionedEsTable1);
- boolean hasException = false;
- EsTableState esTableState = null;
- try {
- esTableState = esStateStore.getTableState(clusterStateStr2, esTable);
- } catch (Exception e) {
- hasException = true;
- }
- assertTrue(hasException);
- assertTrue(esTableState == null);
- }
-
- private static String loadJsonFromFile(String fileName) throws IOException, URISyntaxException {
- File file = new File(EsStateStoreTest.class.getClassLoader().getResource(fileName).toURI());
- InputStream is = new FileInputStream(file);
- BufferedReader br = new BufferedReader(new InputStreamReader(is));
- StringBuilder jsonStr = new StringBuilder();
- String line = "";
- while ((line = br.readLine()) != null) {
- jsonStr.append(line);
- }
- br.close();
- is.close();
- return jsonStr.toString();
- }
-}
diff --git a/fe/src/test/java/org/apache/doris/es/EsUtilTest.java b/fe/src/test/java/org/apache/doris/external/elasticsearch/EsUtilTest.java
similarity index 97%
rename from fe/src/test/java/org/apache/doris/es/EsUtilTest.java
rename to fe/src/test/java/org/apache/doris/external/elasticsearch/EsUtilTest.java
index 876a8ea..b611ae4 100644
--- a/fe/src/test/java/org/apache/doris/es/EsUtilTest.java
+++ b/fe/src/test/java/org/apache/doris/external/elasticsearch/EsUtilTest.java
@@ -15,7 +15,7 @@
// specific language governing permissions and limitations
// under the License.
-package org.apache.doris.es;
+package org.apache.doris.external.elasticsearch;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
@@ -25,8 +25,6 @@ import org.json.JSONException;
import org.json.JSONObject;
import org.junit.Test;
-import org.apache.doris.external.EsUtil;
-
public class EsUtilTest {
private String jsonStr = "{\"settings\": {\n"
diff --git a/fe/src/test/java/org/apache/doris/external/elasticsearch/QueryBuildersTest.java b/fe/src/test/java/org/apache/doris/external/elasticsearch/QueryBuildersTest.java
new file mode 100644
index 0000000..ebd0243
--- /dev/null
+++ b/fe/src/test/java/org/apache/doris/external/elasticsearch/QueryBuildersTest.java
@@ -0,0 +1,173 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.external.elasticsearch;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.concurrent.atomic.AtomicBoolean;
+import org.apache.doris.external.elasticsearch.QueryBuilders;
+import org.junit.Test;
+
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Check that internal queries are correctly converted to ES search query (as JSON)
+ */
+public class QueryBuildersTest {
+
+ private final ObjectMapper mapper = new ObjectMapper();
+
+
+ @Test
+ public void testTermQuery() throws Exception {
+ assertEquals("{\"term\":{\"k\":\"aaaa\"}}",
+ toJson(QueryBuilders.termQuery("k", "aaaa")));
+ assertEquals("{\"term\":{\"aaaa\":\"k\"}}",
+ toJson(QueryBuilders.termQuery("aaaa", "k")));
+ assertEquals("{\"term\":{\"k\":0}}",
+ toJson(QueryBuilders.termQuery("k", (byte) 0)));
+ assertEquals("{\"term\":{\"k\":123}}",
+ toJson(QueryBuilders.termQuery("k", (long) 123)));
+ assertEquals("{\"term\":{\"k\":41}}",
+ toJson(QueryBuilders.termQuery("k", (short) 41)));
+ assertEquals("{\"term\":{\"k\":128}}",
+ toJson(QueryBuilders.termQuery("k", 128)));
+ assertEquals("{\"term\":{\"k\":42.42}}",
+ toJson(QueryBuilders.termQuery("k", 42.42D)));
+ assertEquals("{\"term\":{\"k\":1.1}}",
+ toJson(QueryBuilders.termQuery("k", 1.1F)));
+ assertEquals("{\"term\":{\"k\":1}}",
+ toJson(QueryBuilders.termQuery("k", new BigDecimal(1))));
+ assertEquals("{\"term\":{\"k\":121}}",
+ toJson(QueryBuilders.termQuery("k", new BigInteger("121"))));
+ assertEquals("{\"term\":{\"k\":true}}",
+ toJson(QueryBuilders.termQuery("k", new AtomicBoolean(true))));
+ }
+
+ @Test
+ public void testTermsQuery() throws Exception {
+
+ assertEquals("{\"terms\":{\"k\":[]}}",
+ toJson(QueryBuilders.termsQuery("k", Collections.emptySet())));
+
+ assertEquals("{\"terms\":{\"k\":[0]}}",
+ toJson(QueryBuilders.termsQuery("k", Collections.singleton(0))));
+
+ assertEquals("{\"terms\":{\"k\":[\"aaa\"]}}",
+ toJson(QueryBuilders.termsQuery("k", Collections.singleton("aaa"))));
+
+ assertEquals("{\"terms\":{\"k\":[\"aaa\",\"bbb\",\"ccc\"]}}",
+ toJson(QueryBuilders.termsQuery("k", Arrays.asList("aaa", "bbb", "ccc"))));
+
+ assertEquals("{\"terms\":{\"k\":[1,2,3]}}",
+ toJson(QueryBuilders.termsQuery("k", Arrays.asList(1, 2, 3))));
+
+ assertEquals("{\"terms\":{\"k\":[1.1,2.2,3.3]}}",
+ toJson(QueryBuilders.termsQuery("k", Arrays.asList(1.1f, 2.2f, 3.3f))));
+
+ assertEquals("{\"terms\":{\"k\":[1.1,2.2,3.3]}}",
+ toJson(QueryBuilders.termsQuery("k", Arrays.asList(1.1d, 2.2d, 3.3d))));
+ }
+
+ @Test
+ public void testBoolQuery() throws Exception {
+ QueryBuilders.QueryBuilder q1 = QueryBuilders.boolQuery()
+ .must(QueryBuilders.termQuery("k", "aaa"));
+
+ assertEquals("{\"bool\":{\"must\":{\"term\":{\"k\":\"aaa\"}}}}",
+ toJson(q1));
+
+ QueryBuilders.QueryBuilder q2 = QueryBuilders.boolQuery()
+ .must(QueryBuilders.termQuery("k1", "aaa")).must(QueryBuilders.termQuery("k2", "bbb"));
+
+ assertEquals("{\"bool\":{\"must\":[{\"term\":{\"k1\":\"aaa\"}},{\"term\":{\"k2\":\"bbb\"}}]}}",
+ toJson(q2));
+
+ QueryBuilders.QueryBuilder q3 = QueryBuilders.boolQuery()
+ .mustNot(QueryBuilders.termQuery("k", "fff"));
+
+ assertEquals("{\"bool\":{\"must_not\":{\"term\":{\"k\":\"fff\"}}}}",
+ toJson(q3));
+
+ QueryBuilders.QueryBuilder q4 = QueryBuilders.rangeQuery("k1").lt(200).gt(-200);
+ QueryBuilders.QueryBuilder q5 = QueryBuilders.termsQuery("k2", Arrays.asList("aaa", "bbb", "ccc"));
+ QueryBuilders.QueryBuilder q6 = QueryBuilders.boolQuery().must(q4).should(q5);
+ assertEquals("{\"bool\":{\"must\":{\"range\":{\"k1\":{\"gt\":-200,\"lt\":200}}},\"should\":{\"terms\":{\"k2\":[\"aaa\",\"bbb\",\"ccc\"]}}}}", toJson(q6));
+ assertEquals("{\"bool\":{\"filter\":[{\"range\":{\"k1\":{\"gt\":-200,\"lt\":200}}},{\"terms\":{\"k2\":[\"aaa\",\"bbb\",\"ccc\"]}}]}}", toJson(QueryBuilders.boolQuery().filter(q4).filter(q5)));
+ assertEquals("{\"bool\":{\"filter\":{\"range\":{\"k1\":{\"gt\":-200,\"lt\":200}}},\"must_not\":{\"terms\":{\"k2\":[\"aaa\",\"bbb\",\"ccc\"]}}}}", toJson(QueryBuilders.boolQuery().filter(q4).mustNot(q5)));
+
+ }
+
+ @Test
+ public void testExistsQuery() throws Exception {
+ assertEquals("{\"exists\":{\"field\":\"k\"}}",
+ toJson(QueryBuilders.existsQuery("k")));
+ }
+
+ @Test
+ public void testRangeQuery() throws Exception {
+ assertEquals("{\"range\":{\"k\":{\"lt\":123}}}",
+ toJson(QueryBuilders.rangeQuery("k").lt(123)));
+ assertEquals("{\"range\":{\"k\":{\"gt\":123}}}",
+ toJson(QueryBuilders.rangeQuery("k").gt(123)));
+ assertEquals("{\"range\":{\"k\":{\"gte\":12345678}}}",
+ toJson(QueryBuilders.rangeQuery("k").gte(12345678)));
+ assertEquals("{\"range\":{\"k\":{\"lte\":12345678}}}",
+ toJson(QueryBuilders.rangeQuery("k").lte(12345678)));
+ assertEquals("{\"range\":{\"k\":{\"gt\":123,\"lt\":345}}}",
+ toJson(QueryBuilders.rangeQuery("k").gt(123).lt(345)));
+ assertEquals("{\"range\":{\"k\":{\"gt\":-456.6,\"lt\":12.3}}}",
+ toJson(QueryBuilders.rangeQuery("k").lt(12.3f).gt(-456.6f)));
+ assertEquals("{\"range\":{\"k\":{\"gt\":6789.33,\"lte\":9999.99}}}",
+ toJson(QueryBuilders.rangeQuery("k").gt(6789.33f).lte(9999.99f)));
+ assertEquals("{\"range\":{\"k\":{\"gte\":1,\"lte\":\"zzz\"}}}",
+ toJson(QueryBuilders.rangeQuery("k").gte(1).lte("zzz")));
+ assertEquals("{\"range\":{\"k\":{\"gte\":\"zzz\"}}}",
+ toJson(QueryBuilders.rangeQuery("k").gte("zzz")));
+ assertEquals("{\"range\":{\"k\":{\"gt\":\"aaa\",\"lt\":\"zzz\"}}}",
+ toJson(QueryBuilders.rangeQuery("k").gt("aaa").lt("zzz")));
+ }
+
+ @Test
+ public void testMatchAllQuery() throws IOException {
+ assertEquals("{\"match_all\":{}}",
+ toJson(QueryBuilders.matchAllQuery()));
+ }
+
+ @Test
+ public void testWildCardQuery() throws IOException {
+ assertEquals("{\"wildcard\":{\"k1\":\"?aa*\"}}",
+ toJson(QueryBuilders.wildcardQuery("k1", "?aa*")));
+ }
+
+ private String toJson(QueryBuilders.QueryBuilder builder) throws IOException {
+ StringWriter writer = new StringWriter();
+ JsonGenerator gen = mapper.getFactory().createGenerator(writer);
+ builder.toJson(gen);
+ gen.flush();
+ gen.close();
+ return writer.toString();
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org