Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

package org.opensearch.sql.expression.operator.predicate;

import java.util.Map;
import java.util.concurrent.TimeUnit;
import org.apache.calcite.plan.RelOptCluster;
import org.apache.calcite.plan.volcano.VolcanoPlanner;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rel.type.StructKind;
import org.apache.calcite.rex.RexBuilder;
import org.apache.calcite.rex.RexNode;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
import org.apache.calcite.sql.type.SqlTypeName;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;
import org.opensearch.sql.calcite.utils.OpenSearchTypeFactory;
import org.opensearch.sql.data.type.ExprCoreType;
import org.opensearch.sql.data.type.ExprType;
import org.opensearch.sql.expression.DSL;
import org.opensearch.sql.expression.Expression;
import org.opensearch.sql.expression.function.BuiltinFunctionName;
import org.opensearch.sql.expression.function.PPLFuncImpTable;
import org.opensearch.sql.opensearch.storage.serde.DefaultExpressionSerializer;
import org.opensearch.sql.opensearch.storage.serde.RelJsonSerializer;

@Warmup(iterations = 1)
@Measurement(iterations = 10)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@State(Scope.Thread)
@Fork(value = 1)
public class ExpressionScriptSerdeBenchmark {

@Benchmark
public void testV2ExpressionSerde() {
DefaultExpressionSerializer defaultSerializer = new DefaultExpressionSerializer();
Expression exprUpper = DSL.upper(DSL.ref("Referer", ExprCoreType.STRING));
Expression exprNotEquals = DSL.notequal(exprUpper, DSL.literal("ABOUT"));

String serializedStr = defaultSerializer.serialize(exprNotEquals);
defaultSerializer.deserialize(serializedStr);
}

@Benchmark
public void testRexNodeJsonSerde() {
RexBuilder rexBuilder = new RexBuilder(OpenSearchTypeFactory.TYPE_FACTORY);
RelOptCluster cluster = RelOptCluster.create(new VolcanoPlanner(), rexBuilder);
RelJsonSerializer relJsonSerializer = new RelJsonSerializer(cluster);
RelDataType rowType =
rexBuilder
.getTypeFactory()
.builder()
.kind(StructKind.FULLY_QUALIFIED)
.add("Referer", rexBuilder.getTypeFactory().createSqlType(SqlTypeName.VARCHAR))
.build();
RexNode rexUpper =
PPLFuncImpTable.INSTANCE.resolve(
rexBuilder,
BuiltinFunctionName.UPPER,
rexBuilder.makeInputRef(rowType.getFieldList().get(0).getType(), 0));
RexNode rexNotEquals =
rexBuilder.makeCall(
SqlStdOperatorTable.NOT_EQUALS, rexUpper, rexBuilder.makeLiteral("ABOUT"));
Map<String, ExprType> fieldTypes = Map.of("Referer", ExprCoreType.STRING);

String serializedStr = relJsonSerializer.serialize(rexNotEquals, rowType, fieldTypes);
relJsonSerializer.deserialize(serializedStr);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@
import static org.opensearch.sql.calcite.utils.UserDefinedFunctionUtils.adaptExprMethodToUDF;
import static org.opensearch.sql.calcite.utils.UserDefinedFunctionUtils.adaptExprMethodWithPropertiesToUDF;

import com.google.common.base.Suppliers;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.function.Supplier;
import org.apache.calcite.adapter.enumerable.NullPolicy;
import org.apache.calcite.adapter.enumerable.RexImpTable;
import org.apache.calcite.adapter.enumerable.RexImpTable.RexCallImplementor;
Expand Down Expand Up @@ -82,6 +84,9 @@
/** Defines functions and operators that are implemented only by PPL */
public class PPLBuiltinOperators extends ReflectiveSqlOperatorTable {

private static final Supplier<PPLBuiltinOperators> INSTANCE =
Suppliers.memoize(() -> (PPLBuiltinOperators) new PPLBuiltinOperators().init());

// Json Functions
public static final SqlOperator JSON = new JsonFunctionImpl().toUDF("JSON");
public static final SqlOperator JSON_ARRAY_LENGTH =
Expand Down Expand Up @@ -354,6 +359,15 @@ public class PPLBuiltinOperators extends ReflectiveSqlOperatorTable {
public static final SqlOperator MULTI_MATCH =
RELEVANCE_QUERY_FUNCTION_INSTANCE.toUDF("multi_match", false);

/**
* Returns the PPL specific operator table, creating it if necessary.
*
* @return PPLBuiltinOperators operator table
*/
public static PPLBuiltinOperators instance() {
return INSTANCE.get();
}

/**
* Invoking an implementor registered in {@link RexImpTable}, need to use reflection since they're
* all private Use method directly in {@link BuiltInMethod} if possible, most operators'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,16 @@ public Expression implement(
return Expressions.call(CidrMatchImplementor.class, "cidrMatch", translatedOperands);
}

public static boolean cidrMatch(ExprIpValue ip, String cidr) {
public static boolean cidrMatch(Object ip, String cidr) {
ExprValue ipValue;
if (ip instanceof ExprIpValue) {
ipValue = (ExprIpValue) ip;
} else {
// Deserialization workaround
ipValue = new ExprIpValue((String) ip);
}
ExprValue cidrValue = ExprValueUtils.stringValue(cidr);
return (boolean) IPFunctions.exprCidrMatch(ip, cidrValue).valueForCalcite();
return (boolean) IPFunctions.exprCidrMatch(ipValue, cidrValue).valueForCalcite();
}

public static boolean cidrMatch(String ip, String cidr) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,4 +94,30 @@ public void supportPartialPushDown_NoPushIfAllFailed() throws IOException {
String expected = loadFromFile("expectedOutput/calcite/explain_partial_filter_push2.json");
assertJsonEqualsIgnoreId(expected, result);
}

@Test
public void supportPartialPushDownScript() throws IOException {
Assume.assumeTrue("This test is only for push down enabled", isPushdownEnabled());
// field `address` is text type without keyword subfield, so we cannot push it down.
// But the second condition can be translated to script, so the second one is pushed down.
String query =
"source=opensearch-sql_test_index_account | where address = '671 Bristol Street' and age -"
+ " 2 = 30 | fields firstname, age, address";
var result = explainQueryToString(query);
String expected =
loadFromFile("expectedOutput/calcite/explain_partial_filter_script_push.json");
assertJsonEqualsIgnoreId(expected, result);
}

// Only for Calcite, as v2 gets unstable serialized string for function
@Test
public void testFilterScriptPushDownExplain() throws Exception {
super.testFilterScriptPushDownExplain();
}

// Only for Calcite, as v2 gets unstable serialized string for function
@Test
public void testFilterFunctionScriptPushDownExplain() throws Exception {
super.testFilterFunctionScriptPushDownExplain();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,9 @@ public void testQ3() throws IOException {
rows(4423, 3055.9365, "1995-02-17 00:00:00", 0));
}

// TODO: Aggregation push down has a hard-coded limit of 1000 buckets for output, so this query
// will not return the correct results with aggregation push down and it's unstable
@Ignore
@Test
public void testQ4() throws IOException {
String ppl = sanitize(loadFromFile("tpch/queries/q4.ppl"));
Expand All @@ -148,11 +151,11 @@ public void testQ4() throws IOException {
actual, schema("o_orderpriority", "string"), schema("order_count", "bigint"));
verifyDataRows(
actual,
rows("1-URGENT", 9),
rows("1-URGENT", 7),
rows("2-HIGH", 7),
rows("3-MEDIUM", 9),
rows("4-NOT SPECIFIED", 8),
rows("5-LOW", 12));
rows("3-MEDIUM", 4),
rows("4-NOT SPECIFIED", 7),
rows("5-LOW", 10));
}

@Test
Expand Down
38 changes: 38 additions & 0 deletions integ-test/src/test/java/org/opensearch/sql/ppl/ExplainIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import static org.opensearch.sql.util.MatcherUtils.assertJsonEqualsIgnoreId;

import java.io.IOException;
import org.junit.Ignore;
import org.junit.jupiter.api.Test;
import org.opensearch.client.ResponseException;
import org.opensearch.sql.legacy.TestUtils;
Expand Down Expand Up @@ -434,6 +435,43 @@ public void testMultiFieldsRelevanceQueryFunctionExplain() throws IOException {
+ " default_operator='or', analyzer=english)"));
}

@Ignore("The serialized string is unstable because of function properties")
@Test
public void testFilterScriptPushDownExplain() throws Exception {
String expected = loadExpectedPlan("explain_filter_script_push.json");
assertJsonEqualsIgnoreId(
expected,
explainQueryToString(
"source=opensearch-sql_test_index_account | where firstname ='Amber' and age - 2 = 30 |"
+ " fields firstname, age"));
}

@Ignore("The serialized string is unstable because of function properties")
@Test
public void testFilterFunctionScriptPushDownExplain() throws Exception {
String expected = loadExpectedPlan("explain_filter_function_script_push.json");
assertJsonEqualsIgnoreId(
expected,
explainQueryToString(
"source=opensearch-sql_test_index_account | where length(firstname) = 5 and abs(age) ="
+ " 32 and balance = 39225 | fields firstname, age"));
}

@Test
public void testDifferentFilterScriptPushDownBehaviorExplain() throws Exception {
String explainedPlan =
explainQueryToString(
"source=opensearch-sql_test_index_account | where firstname != '' | fields firstname");
if (isCalciteEnabled()) {
// Calcite pushdown as pure filter query
String expected = loadExpectedPlan("explain_filter_script_push_diff.json");
assertJsonEqualsIgnoreId(expected, explainedPlan);
} else {
// V2 pushdown as script
assertTrue(explainedPlan.contains("{\\\"script\\\":"));
}
}

protected String loadExpectedPlan(String fileName) throws IOException {
String prefix;
if (isCalciteEnabled()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,9 @@ public void not_pushdown_throws_exception() throws IOException {
String query1 =
"SOURCE="
+ TEST_INDEX_BEER
+ " | EVAL answerId = AcceptedAnswerId + 1"
+ " | WHERE simple_query_string(['Tags'], 'taste') and answerId > 200";
+ " | STATS count(AcceptedAnswerId) as count"
+ " | EVAL dateStr = makedate(2025, count)"
+ " | WHERE simple_query_string(['dateStr'], 'taste')";
assertThrows(Exception.class, () -> executeQuery(query1));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@
import static org.hamcrest.CoreMatchers.containsString;
import static org.opensearch.sql.legacy.TestsConstants.TEST_INDEX_ACCOUNT;
import static org.opensearch.sql.legacy.TestsConstants.TEST_INDEX_BANK_WITH_NULL_VALUES;
import static org.opensearch.sql.legacy.TestsConstants.TEST_INDEX_DATE_TIME;
import static org.opensearch.sql.util.MatcherUtils.rows;
import static org.opensearch.sql.util.MatcherUtils.schema;
import static org.opensearch.sql.util.MatcherUtils.verifyDataRows;
import static org.opensearch.sql.util.MatcherUtils.verifySchema;

import java.io.IOException;
import java.util.stream.Collectors;
Expand All @@ -26,6 +29,7 @@ public void init() throws Exception {
loadIndex(Index.ACCOUNT);
loadIndex(Index.BANK_WITH_NULL_VALUES);
loadIndex(Index.GAME_OF_THRONES);
loadIndex(Index.DATETIME);
}

@Test
Expand Down Expand Up @@ -204,4 +208,51 @@ protected String getIncompatibleTypeErrMsg() {
.collect(Collectors.joining(",", "{", "}")),
"[LONG,STRING]");
}

@Test
public void testFilterScriptPushDown() throws IOException {
JSONObject actual =
executeQuery(
String.format(
"source=%s | where firstname ='Amber' and age - 2.0 = 30 | fields firstname, age",
TEST_INDEX_ACCOUNT));
verifySchema(actual, schema("firstname", "string"), schema("age", "bigint"));
verifyDataRows(actual, rows("Amber", 32));
}

@Test
public void testFilterScriptPushDownWithCalciteStdFunction() throws IOException {
JSONObject actual =
executeQuery(
String.format(
"source=%s | where length(firstname) = 5 and abs(age) = 32 and balance = 39225 |"
+ " fields firstname, age",
TEST_INDEX_ACCOUNT));
verifySchema(actual, schema("firstname", "string"), schema("age", "bigint"));
verifyDataRows(actual, rows("Amber", 32));
}

@Test
public void testFilterScriptPushDownWithPPLBuiltInFunction() throws IOException {
JSONObject actual =
executeQuery(
String.format("source=%s | where month(login_time) = 1", TEST_INDEX_DATE_TIME));
verifySchema(actual, schema("birthday", "timestamp"), schema("login_time", "timestamp"));
verifyDataRows(
actual,
rows(null, "2015-01-01 00:00:00"),
rows(null, "2015-01-01 12:10:30"),
rows(null, "1970-01-19 08:31:22.955"));
}

@Test
public void testFilterScriptPushDownWithCalciteStdLibraryFunction() throws IOException {
JSONObject actual =
executeQuery(
String.format(
"source=%s | where left(firstname, 3) = 'Ama' | fields firstname",
TEST_INDEX_ACCOUNT));
verifySchema(actual, schema("firstname", "string"));
verifyDataRows(actual, rows("Amalia"), rows("Amanda"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,11 @@ public static void assertJsonEqualsIgnoreId(String expected, String actual) {
}

private static String cleanUpId(String s) {
return eliminatePid(eliminateRelId(s));
return eliminateTimeStamp(eliminatePid(eliminateRelId(s)));
}

private static String eliminateTimeStamp(String s) {
return s.replaceAll("\\\\\"utcTimestamp\\\\\":\\d+", "\\\\\"utcTimestamp\\\\\":*");
}

private static String eliminateRelId(String s) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"calcite": {
"logical": "LogicalProject(firstname=[$1], age=[$8])\n LogicalFilter(condition=[AND(=(CHAR_LENGTH($1), 5), =(ABS($8), 32), =($3, 39225))])\n CalciteLogicalIndexScan(table=[[OpenSearch, opensearch-sql_test_index_account]])\n",
"physical": "CalciteEnumerableIndexScan(table=[[OpenSearch, opensearch-sql_test_index_account]], PushDownContext=[[PROJECT->[firstname, balance, age], SCRIPT->AND(=(CHAR_LENGTH($0), 5), =(ABS($2), 32), =($1, 39225)), PROJECT->[firstname, age]], OpenSearchRequestBuilder(sourceBuilder={\"from\":0,\"timeout\":\"1m\",\"query\":{\"bool\":{\"must\":[{\"script\":{\"script\":{\"source\":\"{\\\"langType\\\":\\\"calcite\\\",\\\"script\\\":\\\"rO0ABXNyABFqYXZhLnV0aWwuQ29sbFNlcleOq7Y6G6gRAwABSQADdGFneHAAAAADdwQAAAAGdAAHcm93VHlwZXQBPnsKICAiZmllbGRzIjogWwogICAgewogICAgICAidHlwZSI6ICJWQVJDSEFSIiwKICAgICAgIm51bGxhYmxlIjogdHJ1ZSwKICAgICAgInByZWNpc2lvbiI6IC0xLAogICAgICAibmFtZSI6ICJmaXJzdG5hbWUiCiAgICB9LAogICAgewogICAgICAidHlwZSI6ICJCSUdJTlQiLAogICAgICAibnVsbGFibGUiOiB0cnVlLAogICAgICAibmFtZSI6ICJiYWxhbmNlIgogICAgfSwKICAgIHsKICAgICAgInR5cGUiOiAiQklHSU5UIiwKICAgICAgIm51bGxhYmxlIjogdHJ1ZSwKICAgICAgIm5hbWUiOiAiYWdlIgogICAgfQogIF0sCiAgIm51bGxhYmxlIjogZmFsc2UKfXQABGV4cHJ0Aa17CiAgIm9wIjogewogICAgIm5hbWUiOiAiPSIsCiAgICAia2luZCI6ICJFUVVBTFMiLAogICAgInN5bnRheCI6ICJCSU5BUlkiCiAgfSwKICAib3BlcmFuZHMiOiBbCiAgICB7CiAgICAgICJvcCI6IHsKICAgICAgICAibmFtZSI6ICJDSEFSX0xFTkdUSCIsCiAgICAgICAgImtpbmQiOiAiQ0hBUl9MRU5HVEgiLAogICAgICAgICJzeW50YXgiOiAiRlVOQ1RJT04iCiAgICAgIH0sCiAgICAgICJvcGVyYW5kcyI6IFsKICAgICAgICB7CiAgICAgICAgICAiaW5wdXQiOiAwLAogICAgICAgICAgIm5hbWUiOiAiJDAiCiAgICAgICAgfQogICAgICBdCiAgICB9LAogICAgewogICAgICAibGl0ZXJhbCI6IDUsCiAgICAgICJ0eXBlIjogewogICAgICAgICJ0eXBlIjogIklOVEVHRVIiLAogICAgICAgICJudWxsYWJsZSI6IGZhbHNlCiAgICAgIH0KICAgIH0KICBdCn10AApmaWVsZFR5cGVzc3IAEWphdmEudXRpbC5IYXNoTWFwBQfawcMWYNEDAAJGAApsb2FkRmFjdG9ySQAJdGhyZXNob2xkeHA/QAAAAAAADHcIAAAAEAAAAAN0AAlmaXJzdG5hbWVzcgA6b3JnLm9wZW5zZWFyY2guc3FsLm9wZW5zZWFyY2guZGF0YS50eXBlLk9wZW5TZWFyY2hUZXh0VHlwZa2Do5ME4zFEAgABTAAGZmllbGRzdAAPTGphdmEvdXRpbC9NYXA7eHIAOm9yZy5vcGVuc2VhcmNoLnNxbC5vcGVuc2VhcmNoLmRhdGEudHlwZS5PcGVuU2VhcmNoRGF0YVR5cGXCY7zKAvoFNQIAA0wADGV4cHJDb3JlVHlwZXQAK0xvcmcvb3BlbnNlYXJjaC9zcWwvZGF0YS90eXBlL0V4cHJDb3JlVHlwZTtMAAttYXBwaW5nVHlwZXQASExvcmcvb3BlbnNlYXJjaC9zcWwvb3BlbnNlYXJjaC9kYXRhL3R5cGUvT3BlblNlYXJjaERhdGFUeXBlJE1hcHBpbmdUeXBlO0wACnByb3BlcnRpZXNxAH4AC3hwfnIAKW9yZy5vcGVuc2VhcmNoLnNxbC5kYXRhLnR5cGUuRXhwckNvcmVUeXBlAAAAAAAAAAASAAB4cgAOamF2YS5sYW5nLkVudW0AAAAAAAAAABIAAHhwdAAHVU5LTk9XTn5yAEZvcmcub3BlbnNlYXJjaC5zcWwub3BlbnNlYXJjaC5kYXRhLnR5cGUuT3BlblNlYXJjaERhdGFUeXBlJE1hcHBpbmdUeXBlAAAAAAAAAAASAAB4cQB+ABF0AARUZXh0c3IAPHNoYWRlZC5jb20uZ29vZ2xlLmNvbW1vbi5jb2xsZWN0LkltbXV0YWJsZU1hcCRTZXJpYWxpemVkRm9ybQAAAAAAAAAAAgACTAAEa2V5c3QAEkxqYXZhL2xhbmcvT2JqZWN0O0wABnZhbHVlc3EAfgAYeHB1cgATW0xqYXZhLmxhbmcuT2JqZWN0O5DOWJ8QcylsAgAAeHAAAAAAdXEAfgAaAAAAAHNxAH4AAAAAAAN3BAAAAAJ0AAdrZXl3b3Jkc3EAfgAMfnEAfgAQdAAGU1RSSU5HfnEAfgAUdAAHS2V5d29yZHEAfgAZeHQAB2JhbGFuY2V+cQB+ABB0AARMT05HdAADYWdlcQB+ACV4eA==\\\"}\",\"lang\":\"opensearch_compounded_script\",\"params\":{\"utcTimestamp\":*}},\"boost\":1.0}},{\"script\":{\"script\":{\"source\":\"{\\\"langType\\\":\\\"calcite\\\",\\\"script\\\":\\\"rO0ABXNyABFqYXZhLnV0aWwuQ29sbFNlcleOq7Y6G6gRAwABSQADdGFneHAAAAADdwQAAAAGdAAHcm93VHlwZXQBPnsKICAiZmllbGRzIjogWwogICAgewogICAgICAidHlwZSI6ICJWQVJDSEFSIiwKICAgICAgIm51bGxhYmxlIjogdHJ1ZSwKICAgICAgInByZWNpc2lvbiI6IC0xLAogICAgICAibmFtZSI6ICJmaXJzdG5hbWUiCiAgICB9LAogICAgewogICAgICAidHlwZSI6ICJCSUdJTlQiLAogICAgICAibnVsbGFibGUiOiB0cnVlLAogICAgICAibmFtZSI6ICJiYWxhbmNlIgogICAgfSwKICAgIHsKICAgICAgInR5cGUiOiAiQklHSU5UIiwKICAgICAgIm51bGxhYmxlIjogdHJ1ZSwKICAgICAgIm5hbWUiOiAiYWdlIgogICAgfQogIF0sCiAgIm51bGxhYmxlIjogZmFsc2UKfXQABGV4cHJ0Aal7CiAgIm9wIjogewogICAgIm5hbWUiOiAiPSIsCiAgICAia2luZCI6ICJFUVVBTFMiLAogICAgInN5bnRheCI6ICJCSU5BUlkiCiAgfSwKICAib3BlcmFuZHMiOiBbCiAgICB7CiAgICAgICJvcCI6IHsKICAgICAgICAibmFtZSI6ICJBQlMiLAogICAgICAgICJraW5kIjogIk9USEVSX0ZVTkNUSU9OIiwKICAgICAgICAic3ludGF4IjogIkZVTkNUSU9OIgogICAgICB9LAogICAgICAib3BlcmFuZHMiOiBbCiAgICAgICAgewogICAgICAgICAgImlucHV0IjogMiwKICAgICAgICAgICJuYW1lIjogIiQyIgogICAgICAgIH0KICAgICAgXQogICAgfSwKICAgIHsKICAgICAgImxpdGVyYWwiOiAzMiwKICAgICAgInR5cGUiOiB7CiAgICAgICAgInR5cGUiOiAiSU5URUdFUiIsCiAgICAgICAgIm51bGxhYmxlIjogZmFsc2UKICAgICAgfQogICAgfQogIF0KfXQACmZpZWxkVHlwZXNzcgARamF2YS51dGlsLkhhc2hNYXAFB9rBwxZg0QMAAkYACmxvYWRGYWN0b3JJAAl0aHJlc2hvbGR4cD9AAAAAAAAMdwgAAAAQAAAAA3QACWZpcnN0bmFtZXNyADpvcmcub3BlbnNlYXJjaC5zcWwub3BlbnNlYXJjaC5kYXRhLnR5cGUuT3BlblNlYXJjaFRleHRUeXBlrYOjkwTjMUQCAAFMAAZmaWVsZHN0AA9MamF2YS91dGlsL01hcDt4cgA6b3JnLm9wZW5zZWFyY2guc3FsLm9wZW5zZWFyY2guZGF0YS50eXBlLk9wZW5TZWFyY2hEYXRhVHlwZcJjvMoC+gU1AgADTAAMZXhwckNvcmVUeXBldAArTG9yZy9vcGVuc2VhcmNoL3NxbC9kYXRhL3R5cGUvRXhwckNvcmVUeXBlO0wAC21hcHBpbmdUeXBldABITG9yZy9vcGVuc2VhcmNoL3NxbC9vcGVuc2VhcmNoL2RhdGEvdHlwZS9PcGVuU2VhcmNoRGF0YVR5cGUkTWFwcGluZ1R5cGU7TAAKcHJvcGVydGllc3EAfgALeHB+cgApb3JnLm9wZW5zZWFyY2guc3FsLmRhdGEudHlwZS5FeHByQ29yZVR5cGUAAAAAAAAAABIAAHhyAA5qYXZhLmxhbmcuRW51bQAAAAAAAAAAEgAAeHB0AAdVTktOT1dOfnIARm9yZy5vcGVuc2VhcmNoLnNxbC5vcGVuc2VhcmNoLmRhdGEudHlwZS5PcGVuU2VhcmNoRGF0YVR5cGUkTWFwcGluZ1R5cGUAAAAAAAAAABIAAHhxAH4AEXQABFRleHRzcgA8c2hhZGVkLmNvbS5nb29nbGUuY29tbW9uLmNvbGxlY3QuSW1tdXRhYmxlTWFwJFNlcmlhbGl6ZWRGb3JtAAAAAAAAAAACAAJMAARrZXlzdAASTGphdmEvbGFuZy9PYmplY3Q7TAAGdmFsdWVzcQB+ABh4cHVyABNbTGphdmEubGFuZy5PYmplY3Q7kM5YnxBzKWwCAAB4cAAAAAB1cQB+ABoAAAAAc3EAfgAAAAAAA3cEAAAAAnQAB2tleXdvcmRzcQB+AAx+cQB+ABB0AAZTVFJJTkd+cQB+ABR0AAdLZXl3b3JkcQB+ABl4dAAHYmFsYW5jZX5xAH4AEHQABExPTkd0AANhZ2VxAH4AJXh4\\\"}\",\"lang\":\"opensearch_compounded_script\",\"params\":{\"utcTimestamp\":*}},\"boost\":1.0}},{\"term\":{\"balance\":{\"value\":39225,\"boost\":1.0}}}],\"adjust_pure_negative\":true,\"boost\":1.0}},\"_source\":{\"includes\":[\"firstname\",\"age\"],\"excludes\":[]},\"sort\":[{\"_doc\":{\"order\":\"asc\"}}]}, requestedTotalSize=2147483647, pageSize=null, startFrom=0)])\n"
}
}
Loading
Loading