Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
1894875
Support filter script push down for calcite
qianheng-aws May 30, 2025
13acaf5
Fix UT
qianheng-aws Jun 23, 2025
b37dc92
Change CompoundedScriptEngine name
qianheng-aws Jun 24, 2025
1abf8aa
Merge remote-tracking branch 'refs/remotes/origin/main' into ScriptPu…
qianheng-aws Jun 24, 2025
bc6ecac
Remove duplicated code after merging main
qianheng-aws Jun 24, 2025
cb3a2fe
Create RelJsonSerializer to serialize RexNode instead of unsafe code …
songkant-aws Jun 26, 2025
700fc29
Fix some IT
songkant-aws Jul 9, 2025
fc77e5e
Add validation logic before script serialization
songkant-aws Jul 10, 2025
aba4fed
Merge branch 'main' into rexnode-json-serialization
songkant-aws Jul 10, 2025
2cf247d
Resolve compilation issue after merge
songkant-aws Jul 10, 2025
3049c0c
Comply with relevance query pushdown
songkant-aws Jul 10, 2025
85f8df0
Add cost computing for script pushdown to balance performance
songkant-aws Jul 11, 2025
18ab9bf
Merge branch 'main' into rexnode-json-serialization
songkant-aws Jul 11, 2025
5b18cc4
Correct test case after merge
songkant-aws Jul 11, 2025
e522bc0
Add V2Expression vs RexNode serde benchmark
songkant-aws Jul 15, 2025
1da69d1
Fix spotless check
songkant-aws Jul 15, 2025
ee67876
Address comments
songkant-aws Jul 16, 2025
c18006a
Fix IT after change
songkant-aws Jul 16, 2025
ffd26a7
Encode langType into script JSON blob
songkant-aws Jul 17, 2025
3ff2f50
Merge branch 'main' into rexnode-json-serialization
songkant-aws Jul 17, 2025
2fee6ee
Merge branch 'main' into rexnode-json-serialization
songkant-aws Jul 17, 2025
08cd417
Fix issue after merge
songkant-aws Jul 17, 2025
fde5cf0
Merge branch 'main' into rexnode-json-serialization
songkant-aws Jul 18, 2025
d2a95ea
Merge branch 'main' into rexnode-json-serialization
songkant-aws Jul 21, 2025
1dd6752
Consolidate with partial pushdown logic after merge
songkant-aws Jul 21, 2025
573552b
Fix UT
songkant-aws Jul 21, 2025
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 @@ -15,6 +15,7 @@

import java.io.IOException;
import org.json.JSONObject;
import org.junit.Ignore;
import org.junit.Test;
import org.opensearch.sql.ppl.PPLIntegTestCase;

Expand Down Expand Up @@ -139,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 @@ -147,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")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add the test:
source=opensearch-sql_test_index_account | where firstname != ''

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@songkant-aws can you add above test case in explain IT?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added the above test. But the test itself is optimized as bool filter query before hitting script pushdown codepath. Ideally we should find a query that is chosen by optimizer. I'm checking if there is one.

@Test
public void testFilterScriptPushDownExplain() throws Exception {
String expected = loadExpectedPlan("explain_filter_script_push.json");
assertJsonEqualsIgnoreId(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we avoid compare all function properties?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a member of FunctionExpression in V2. It has a reference of current Instant object. So the generated bytes string is not stable. It can't be avoided now.

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')";
Comment on lines +177 to +179
Copy link
Contributor Author

@songkant-aws songkant-aws Jul 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change to more complex ppl query because now most of EVAL filters can be pushed down as script expression. Adding agg before filters will prevent them pushdown.

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 @@ -403,7 +403,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