EQL: Add implicit ordering on timestamp (#53004)
QL: Move Sort base class from SQL to QL (cherry picked from commit 798015b7bbd565e9c4222724614baeb432c7c2b3)
This commit is contained in:
parent
f8396e8d15
commit
712e0c05cd
|
@ -37,7 +37,7 @@ public class EqlSearchRequest implements Validatable, ToXContentObject {
|
||||||
private IndicesOptions indicesOptions = IndicesOptions.fromOptions(false, false, true, false);
|
private IndicesOptions indicesOptions = IndicesOptions.fromOptions(false, false, true, false);
|
||||||
|
|
||||||
private QueryBuilder filter = null;
|
private QueryBuilder filter = null;
|
||||||
private String timestampField = "@timestamp";
|
private String timestampField = "timestamp";
|
||||||
private String eventTypeField = "event_type";
|
private String eventTypeField = "event_type";
|
||||||
private String implicitJoinKeyField = "agent.id";
|
private String implicitJoinKeyField = "agent.id";
|
||||||
private int fetchSize = 50;
|
private int fetchSize = 50;
|
||||||
|
|
|
@ -79,6 +79,7 @@ public class EqlIT extends ESRestHighLevelClientTestCase {
|
||||||
sb.append(",");
|
sb.append(",");
|
||||||
}
|
}
|
||||||
sb.append("\"event_type\": \"process\",");
|
sb.append("\"event_type\": \"process\",");
|
||||||
|
sb.append("\"timestamp\": \"2020-02-03T12:34:56Z\",");
|
||||||
sb.append("\"serial_event_id\": 1");
|
sb.append("\"serial_event_id\": 1");
|
||||||
sb.append("}");
|
sb.append("}");
|
||||||
doc1.setJsonEntity(sb.toString());
|
doc1.setJsonEntity(sb.toString());
|
||||||
|
|
|
@ -36,6 +36,7 @@ specified in the `query` parameter. The EQL query matches events with an
|
||||||
GET sec_logs/_eql/search
|
GET sec_logs/_eql/search
|
||||||
{
|
{
|
||||||
"event_type_field": "event.category",
|
"event_type_field": "event.category",
|
||||||
|
"timestamp_field": "@timestamp",
|
||||||
"query": """
|
"query": """
|
||||||
process where process.name == "cmd.exe"
|
process where process.name == "cmd.exe"
|
||||||
"""
|
"""
|
||||||
|
@ -62,7 +63,7 @@ The API returns the following response containing the matching event:
|
||||||
"_index": "sec_logs",
|
"_index": "sec_logs",
|
||||||
"_type": "_doc",
|
"_type": "_doc",
|
||||||
"_id": "1",
|
"_id": "1",
|
||||||
"_score": 0.9400072,
|
"_score": null,
|
||||||
"_source": {
|
"_source": {
|
||||||
"@timestamp": "2020-12-07T11:06:07.000Z",
|
"@timestamp": "2020-12-07T11:06:07.000Z",
|
||||||
"agent": {
|
"agent": {
|
||||||
|
@ -75,7 +76,8 @@ The API returns the following response containing the matching event:
|
||||||
"name": "cmd.exe",
|
"name": "cmd.exe",
|
||||||
"path": "C:\\Windows\\System32\\cmd.exe"
|
"path": "C:\\Windows\\System32\\cmd.exe"
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"sort" : [1607339167000]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -99,6 +101,7 @@ field.
|
||||||
GET sec_logs/_eql/search
|
GET sec_logs/_eql/search
|
||||||
{
|
{
|
||||||
"event_type_field": "file.type",
|
"event_type_field": "file.type",
|
||||||
|
"timestamp_field": "@timestamp",
|
||||||
"query": """
|
"query": """
|
||||||
file where agent.id == "8a4f500d"
|
file where agent.id == "8a4f500d"
|
||||||
"""
|
"""
|
||||||
|
@ -146,6 +149,7 @@ filtered documents.
|
||||||
GET sec_logs/_eql/search
|
GET sec_logs/_eql/search
|
||||||
{
|
{
|
||||||
"event_type_field": "event.category",
|
"event_type_field": "event.category",
|
||||||
|
"timestamp_field": "@timestamp",
|
||||||
"filter": {
|
"filter": {
|
||||||
"range" : {
|
"range" : {
|
||||||
"file.size" : {
|
"file.size" : {
|
||||||
|
|
|
@ -8,6 +8,7 @@ setup:
|
||||||
_index: eql_test
|
_index: eql_test
|
||||||
_id: 1
|
_id: 1
|
||||||
- event_type: process
|
- event_type: process
|
||||||
|
timestamp: 2020-02-03T12:34:56Z
|
||||||
user: SYSTEM
|
user: SYSTEM
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
|
@ -10,7 +10,7 @@ public final class RequestDefaults {
|
||||||
|
|
||||||
private RequestDefaults() {}
|
private RequestDefaults() {}
|
||||||
|
|
||||||
public static final String FIELD_TIMESTAMP = "@timestamp";
|
public static final String FIELD_TIMESTAMP = "timestamp";
|
||||||
public static final String FIELD_EVENT_TYPE = "event_type";
|
public static final String FIELD_EVENT_TYPE = "event_type";
|
||||||
public static final String IMPLICIT_JOIN_KEY = "agent.id";
|
public static final String IMPLICIT_JOIN_KEY = "agent.id";
|
||||||
|
|
||||||
|
|
|
@ -7,21 +7,26 @@ package org.elasticsearch.xpack.eql.execution.search;
|
||||||
|
|
||||||
import org.elasticsearch.index.query.QueryBuilder;
|
import org.elasticsearch.index.query.QueryBuilder;
|
||||||
import org.elasticsearch.search.builder.SearchSourceBuilder;
|
import org.elasticsearch.search.builder.SearchSourceBuilder;
|
||||||
import org.elasticsearch.search.fetch.StoredFieldsContext;
|
|
||||||
import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
|
import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
|
||||||
|
import org.elasticsearch.search.sort.FieldSortBuilder;
|
||||||
|
import org.elasticsearch.search.sort.NestedSortBuilder;
|
||||||
|
import org.elasticsearch.search.sort.ScriptSortBuilder.ScriptSortType;
|
||||||
|
import org.elasticsearch.search.sort.SortBuilder;
|
||||||
import org.elasticsearch.xpack.eql.querydsl.container.QueryContainer;
|
import org.elasticsearch.xpack.eql.querydsl.container.QueryContainer;
|
||||||
|
import org.elasticsearch.xpack.ql.expression.Attribute;
|
||||||
|
import org.elasticsearch.xpack.ql.expression.FieldAttribute;
|
||||||
|
import org.elasticsearch.xpack.ql.querydsl.container.AttributeSort;
|
||||||
|
import org.elasticsearch.xpack.ql.querydsl.container.ScriptSort;
|
||||||
|
import org.elasticsearch.xpack.ql.querydsl.container.Sort;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static java.util.Collections.singletonList;
|
|
||||||
import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
|
import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
|
||||||
|
import static org.elasticsearch.search.sort.SortBuilders.fieldSort;
|
||||||
|
import static org.elasticsearch.search.sort.SortBuilders.scriptSort;
|
||||||
|
|
||||||
public abstract class SourceGenerator {
|
public abstract class SourceGenerator {
|
||||||
|
|
||||||
private SourceGenerator() {}
|
private SourceGenerator() {}
|
||||||
|
|
||||||
private static final List<String> NO_STORED_FIELD = singletonList(StoredFieldsContext._NONE_);
|
|
||||||
|
|
||||||
public static SearchSourceBuilder sourceBuilder(QueryContainer container, QueryBuilder filter, Integer size) {
|
public static SearchSourceBuilder sourceBuilder(QueryContainer container, QueryBuilder filter, Integer size) {
|
||||||
QueryBuilder finalQuery = null;
|
QueryBuilder finalQuery = null;
|
||||||
// add the source
|
// add the source
|
||||||
|
@ -38,8 +43,9 @@ public abstract class SourceGenerator {
|
||||||
}
|
}
|
||||||
|
|
||||||
final SearchSourceBuilder source = new SearchSourceBuilder();
|
final SearchSourceBuilder source = new SearchSourceBuilder();
|
||||||
source.query(finalQuery);
|
|
||||||
|
|
||||||
|
source.query(finalQuery);
|
||||||
|
sorting(container, source);
|
||||||
source.fetchSource(FetchSourceContext.FETCH_SOURCE);
|
source.fetchSource(FetchSourceContext.FETCH_SOURCE);
|
||||||
|
|
||||||
// set fetch size
|
// set fetch size
|
||||||
|
@ -54,6 +60,60 @@ public abstract class SourceGenerator {
|
||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void sorting(QueryContainer container, SearchSourceBuilder source) {
|
||||||
|
for (Sort sortable : container.sort().values()) {
|
||||||
|
SortBuilder<?> sortBuilder = null;
|
||||||
|
|
||||||
|
if (sortable instanceof AttributeSort) {
|
||||||
|
AttributeSort as = (AttributeSort) sortable;
|
||||||
|
Attribute attr = as.attribute();
|
||||||
|
|
||||||
|
// sorting only works on not-analyzed fields - look for a multi-field replacement
|
||||||
|
if (attr instanceof FieldAttribute) {
|
||||||
|
FieldAttribute fa = ((FieldAttribute) attr).exactAttribute();
|
||||||
|
|
||||||
|
sortBuilder = fieldSort(fa.name())
|
||||||
|
.missing(as.missing().position())
|
||||||
|
.unmappedType(fa.dataType().esType());
|
||||||
|
|
||||||
|
if (fa.isNested()) {
|
||||||
|
FieldSortBuilder fieldSort = fieldSort(fa.name())
|
||||||
|
.missing(as.missing().position())
|
||||||
|
.unmappedType(fa.dataType().esType());
|
||||||
|
|
||||||
|
NestedSortBuilder newSort = new NestedSortBuilder(fa.nestedParent().name());
|
||||||
|
NestedSortBuilder nestedSort = fieldSort.getNestedSort();
|
||||||
|
|
||||||
|
if (nestedSort == null) {
|
||||||
|
fieldSort.setNestedSort(newSort);
|
||||||
|
} else {
|
||||||
|
while (nestedSort.getNestedSort() != null) {
|
||||||
|
nestedSort = nestedSort.getNestedSort();
|
||||||
|
}
|
||||||
|
nestedSort.setNestedSort(newSort);
|
||||||
|
}
|
||||||
|
|
||||||
|
nestedSort = newSort;
|
||||||
|
|
||||||
|
if (container.query() != null) {
|
||||||
|
container.query().enrichNestedSort(nestedSort);
|
||||||
|
}
|
||||||
|
sortBuilder = fieldSort;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (sortable instanceof ScriptSort) {
|
||||||
|
ScriptSort ss = (ScriptSort) sortable;
|
||||||
|
sortBuilder = scriptSort(ss.script().toPainless(),
|
||||||
|
ss.script().outputType().isNumeric() ? ScriptSortType.NUMBER : ScriptSortType.STRING);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sortBuilder != null) {
|
||||||
|
sortBuilder.order(sortable.direction().asOrder());
|
||||||
|
source.sort(sortBuilder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void optimize(QueryContainer query, SearchSourceBuilder builder) {
|
private static void optimize(QueryContainer query, SearchSourceBuilder builder) {
|
||||||
if (query.shouldTrackHits()) {
|
if (query.shouldTrackHits()) {
|
||||||
builder.trackTotalHits(true);
|
builder.trackTotalHits(true);
|
||||||
|
|
|
@ -7,15 +7,19 @@ package org.elasticsearch.xpack.eql.parser;
|
||||||
|
|
||||||
import org.elasticsearch.xpack.ql.expression.Expression;
|
import org.elasticsearch.xpack.ql.expression.Expression;
|
||||||
import org.elasticsearch.xpack.ql.expression.Literal;
|
import org.elasticsearch.xpack.ql.expression.Literal;
|
||||||
|
import org.elasticsearch.xpack.ql.expression.Order;
|
||||||
import org.elasticsearch.xpack.ql.expression.UnresolvedAttribute;
|
import org.elasticsearch.xpack.ql.expression.UnresolvedAttribute;
|
||||||
import org.elasticsearch.xpack.ql.expression.predicate.logical.And;
|
import org.elasticsearch.xpack.ql.expression.predicate.logical.And;
|
||||||
import org.elasticsearch.xpack.ql.expression.predicate.operator.comparison.Equals;
|
import org.elasticsearch.xpack.ql.expression.predicate.operator.comparison.Equals;
|
||||||
import org.elasticsearch.xpack.ql.plan.logical.Filter;
|
import org.elasticsearch.xpack.ql.plan.logical.Filter;
|
||||||
import org.elasticsearch.xpack.ql.plan.logical.LogicalPlan;
|
import org.elasticsearch.xpack.ql.plan.logical.LogicalPlan;
|
||||||
|
import org.elasticsearch.xpack.ql.plan.logical.OrderBy;
|
||||||
import org.elasticsearch.xpack.ql.plan.logical.UnresolvedRelation;
|
import org.elasticsearch.xpack.ql.plan.logical.UnresolvedRelation;
|
||||||
import org.elasticsearch.xpack.ql.tree.Source;
|
import org.elasticsearch.xpack.ql.tree.Source;
|
||||||
import org.elasticsearch.xpack.ql.type.DataTypes;
|
import org.elasticsearch.xpack.ql.type.DataTypes;
|
||||||
|
|
||||||
|
import static java.util.Collections.singletonList;
|
||||||
|
|
||||||
public abstract class LogicalPlanBuilder extends ExpressionBuilder {
|
public abstract class LogicalPlanBuilder extends ExpressionBuilder {
|
||||||
|
|
||||||
private final ParserParams params;
|
private final ParserParams params;
|
||||||
|
@ -40,6 +44,11 @@ public abstract class LogicalPlanBuilder extends ExpressionBuilder {
|
||||||
condition = new And(source, eventMatch, condition);
|
condition = new And(source, eventMatch, condition);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Filter(source(ctx), new UnresolvedRelation(Source.EMPTY, null, "", false, ""), condition);
|
Filter filter = new Filter(source, new UnresolvedRelation(Source.EMPTY, null, "", false, ""), condition);
|
||||||
|
// add implicit sorting - when pipes are added, this would better seat there (as a default pipe)
|
||||||
|
Order order = new Order(source, new UnresolvedAttribute(source, params.fieldTimestamp()), Order.OrderDirection.ASC,
|
||||||
|
Order.NullsPosition.FIRST);
|
||||||
|
OrderBy orderBy = new OrderBy(source, filter, singletonList(order));
|
||||||
|
return orderBy;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,12 +6,21 @@
|
||||||
|
|
||||||
package org.elasticsearch.xpack.eql.planner;
|
package org.elasticsearch.xpack.eql.planner;
|
||||||
|
|
||||||
|
import org.elasticsearch.xpack.eql.EqlIllegalArgumentException;
|
||||||
import org.elasticsearch.xpack.eql.plan.physical.EsQueryExec;
|
import org.elasticsearch.xpack.eql.plan.physical.EsQueryExec;
|
||||||
import org.elasticsearch.xpack.eql.plan.physical.FilterExec;
|
import org.elasticsearch.xpack.eql.plan.physical.FilterExec;
|
||||||
|
import org.elasticsearch.xpack.eql.plan.physical.OrderExec;
|
||||||
import org.elasticsearch.xpack.eql.plan.physical.PhysicalPlan;
|
import org.elasticsearch.xpack.eql.plan.physical.PhysicalPlan;
|
||||||
import org.elasticsearch.xpack.eql.querydsl.container.QueryContainer;
|
import org.elasticsearch.xpack.eql.querydsl.container.QueryContainer;
|
||||||
import org.elasticsearch.xpack.ql.expression.Attribute;
|
import org.elasticsearch.xpack.ql.expression.Attribute;
|
||||||
|
import org.elasticsearch.xpack.ql.expression.Expression;
|
||||||
|
import org.elasticsearch.xpack.ql.expression.Expressions;
|
||||||
|
import org.elasticsearch.xpack.ql.expression.FieldAttribute;
|
||||||
|
import org.elasticsearch.xpack.ql.expression.Order;
|
||||||
import org.elasticsearch.xpack.ql.planner.ExpressionTranslators;
|
import org.elasticsearch.xpack.ql.planner.ExpressionTranslators;
|
||||||
|
import org.elasticsearch.xpack.ql.querydsl.container.AttributeSort;
|
||||||
|
import org.elasticsearch.xpack.ql.querydsl.container.Sort.Direction;
|
||||||
|
import org.elasticsearch.xpack.ql.querydsl.container.Sort.Missing;
|
||||||
import org.elasticsearch.xpack.ql.querydsl.query.Query;
|
import org.elasticsearch.xpack.ql.querydsl.query.Query;
|
||||||
import org.elasticsearch.xpack.ql.rule.Rule;
|
import org.elasticsearch.xpack.ql.rule.Rule;
|
||||||
import org.elasticsearch.xpack.ql.rule.RuleExecutor;
|
import org.elasticsearch.xpack.ql.rule.RuleExecutor;
|
||||||
|
@ -27,7 +36,7 @@ class QueryFolder extends RuleExecutor<PhysicalPlan> {
|
||||||
@Override
|
@Override
|
||||||
protected Iterable<RuleExecutor<PhysicalPlan>.Batch> batches() {
|
protected Iterable<RuleExecutor<PhysicalPlan>.Batch> batches() {
|
||||||
Batch fold = new Batch("Fold queries",
|
Batch fold = new Batch("Fold queries",
|
||||||
new FoldFilter()
|
new FoldFilter(), new FoldOrderBy()
|
||||||
);
|
);
|
||||||
Batch finish = new Batch("Finish query", Limiter.ONCE,
|
Batch finish = new Batch("Finish query", Limiter.ONCE,
|
||||||
new PlanOutputToQueryRef()
|
new PlanOutputToQueryRef()
|
||||||
|
@ -57,6 +66,38 @@ class QueryFolder extends RuleExecutor<PhysicalPlan> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class FoldOrderBy extends FoldingRule<OrderExec> {
|
||||||
|
@Override
|
||||||
|
protected PhysicalPlan rule(OrderExec plan) {
|
||||||
|
if (plan.child() instanceof EsQueryExec) {
|
||||||
|
EsQueryExec exec = (EsQueryExec) plan.child();
|
||||||
|
QueryContainer qContainer = exec.queryContainer();
|
||||||
|
|
||||||
|
for (Order order : plan.order()) {
|
||||||
|
Direction direction = Direction.from(order.direction());
|
||||||
|
Missing missing = Missing.from(order.nullsPosition());
|
||||||
|
|
||||||
|
// check whether sorting is on an group (and thus nested agg) or field
|
||||||
|
Expression orderExpression = order.child();
|
||||||
|
|
||||||
|
String lookup = Expressions.id(orderExpression);
|
||||||
|
|
||||||
|
// field
|
||||||
|
if (orderExpression instanceof FieldAttribute) {
|
||||||
|
qContainer = qContainer.addSort(lookup, new AttributeSort((FieldAttribute) orderExpression, direction, missing));
|
||||||
|
}
|
||||||
|
// unknown
|
||||||
|
else {
|
||||||
|
throw new EqlIllegalArgumentException("unsupported sorting expression {}", orderExpression);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return exec.with(qContainer);
|
||||||
|
}
|
||||||
|
return plan;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static class PlanOutputToQueryRef extends FoldingRule<EsQueryExec> {
|
private static class PlanOutputToQueryRef extends FoldingRule<EsQueryExec> {
|
||||||
@Override
|
@Override
|
||||||
protected PhysicalPlan rule(EsQueryExec exec) {
|
protected PhysicalPlan rule(EsQueryExec exec) {
|
||||||
|
|
|
@ -19,14 +19,18 @@ import org.elasticsearch.xpack.ql.expression.Expression;
|
||||||
import org.elasticsearch.xpack.ql.expression.Expressions;
|
import org.elasticsearch.xpack.ql.expression.Expressions;
|
||||||
import org.elasticsearch.xpack.ql.expression.FieldAttribute;
|
import org.elasticsearch.xpack.ql.expression.FieldAttribute;
|
||||||
import org.elasticsearch.xpack.ql.expression.gen.pipeline.ConstantInput;
|
import org.elasticsearch.xpack.ql.expression.gen.pipeline.ConstantInput;
|
||||||
|
import org.elasticsearch.xpack.ql.querydsl.container.Sort;
|
||||||
import org.elasticsearch.xpack.ql.querydsl.query.Query;
|
import org.elasticsearch.xpack.ql.querydsl.query.Query;
|
||||||
import org.elasticsearch.xpack.ql.type.DataTypes;
|
import org.elasticsearch.xpack.ql.type.DataTypes;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
import static java.util.Collections.emptyList;
|
import static java.util.Collections.emptyList;
|
||||||
|
import static java.util.Collections.emptyMap;
|
||||||
import static org.elasticsearch.xpack.ql.util.CollectionUtils.combine;
|
import static org.elasticsearch.xpack.ql.util.CollectionUtils.combine;
|
||||||
|
|
||||||
public class QueryContainer {
|
public class QueryContainer {
|
||||||
|
@ -37,17 +41,19 @@ public class QueryContainer {
|
||||||
// list of fields available in the output
|
// list of fields available in the output
|
||||||
private final List<Tuple<FieldExtraction, String>> fields;
|
private final List<Tuple<FieldExtraction, String>> fields;
|
||||||
|
|
||||||
|
private final Map<String, Sort> sort;
|
||||||
private final boolean trackHits;
|
private final boolean trackHits;
|
||||||
private final boolean includeFrozen;
|
private final boolean includeFrozen;
|
||||||
|
|
||||||
public QueryContainer() {
|
public QueryContainer() {
|
||||||
this(null, emptyList(), AttributeMap.emptyAttributeMap(), false, false);
|
this(null, emptyList(), AttributeMap.emptyAttributeMap(), emptyMap(), false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private QueryContainer(Query query, List<Tuple<FieldExtraction, String>> fields, AttributeMap<Expression> attributes, boolean trackHits,
|
private QueryContainer(Query query, List<Tuple<FieldExtraction, String>> fields, AttributeMap<Expression> attributes,
|
||||||
boolean includeFrozen) {
|
Map<String, Sort> sort, boolean trackHits, boolean includeFrozen) {
|
||||||
this.query = query;
|
this.query = query;
|
||||||
this.fields = fields;
|
this.fields = fields;
|
||||||
|
this.sort = sort;
|
||||||
this.attributes = attributes;
|
this.attributes = attributes;
|
||||||
this.trackHits = trackHits;
|
this.trackHits = trackHits;
|
||||||
this.includeFrozen = includeFrozen;
|
this.includeFrozen = includeFrozen;
|
||||||
|
@ -65,12 +71,16 @@ public class QueryContainer {
|
||||||
return fields;
|
return fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Map<String, Sort> sort() {
|
||||||
|
return sort;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean shouldTrackHits() {
|
public boolean shouldTrackHits() {
|
||||||
return trackHits;
|
return trackHits;
|
||||||
}
|
}
|
||||||
|
|
||||||
public QueryContainer with(Query q) {
|
public QueryContainer with(Query q) {
|
||||||
return new QueryContainer(q, fields, attributes, trackHits, includeFrozen);
|
return new QueryContainer(q, fields, attributes, sort, trackHits, includeFrozen);
|
||||||
}
|
}
|
||||||
|
|
||||||
public QueryContainer addColumn(Attribute attr) {
|
public QueryContainer addColumn(Attribute attr) {
|
||||||
|
@ -98,6 +108,12 @@ public class QueryContainer {
|
||||||
throw new EqlIllegalArgumentException("Unknown output attribute {}", attr);
|
throw new EqlIllegalArgumentException("Unknown output attribute {}", attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public QueryContainer addSort(String expressionId, Sort sortable) {
|
||||||
|
Map<String, Sort> newSort = new LinkedHashMap<>(this.sort);
|
||||||
|
newSort.put(expressionId, sortable);
|
||||||
|
return new QueryContainer(query, fields, attributes, newSort, trackHits, includeFrozen);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// reference methods
|
// reference methods
|
||||||
//
|
//
|
||||||
|
@ -139,7 +155,7 @@ public class QueryContainer {
|
||||||
}
|
}
|
||||||
|
|
||||||
public QueryContainer addColumn(FieldExtraction ref, String id) {
|
public QueryContainer addColumn(FieldExtraction ref, String id) {
|
||||||
return new QueryContainer(query, combine(fields, new Tuple<>(ref, id)), attributes, trackHits, includeFrozen);
|
return new QueryContainer(query, combine(fields, new Tuple<>(ref, id)), attributes, sort, trackHits, includeFrozen);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -8,11 +8,18 @@ package org.elasticsearch.xpack.eql.parser;
|
||||||
|
|
||||||
import org.elasticsearch.test.ESTestCase;
|
import org.elasticsearch.test.ESTestCase;
|
||||||
import org.elasticsearch.xpack.ql.expression.Expression;
|
import org.elasticsearch.xpack.ql.expression.Expression;
|
||||||
|
import org.elasticsearch.xpack.ql.expression.Order;
|
||||||
|
import org.elasticsearch.xpack.ql.expression.Order.NullsPosition;
|
||||||
|
import org.elasticsearch.xpack.ql.expression.Order.OrderDirection;
|
||||||
|
import org.elasticsearch.xpack.ql.expression.UnresolvedAttribute;
|
||||||
import org.elasticsearch.xpack.ql.plan.logical.Filter;
|
import org.elasticsearch.xpack.ql.plan.logical.Filter;
|
||||||
import org.elasticsearch.xpack.ql.plan.logical.LogicalPlan;
|
import org.elasticsearch.xpack.ql.plan.logical.LogicalPlan;
|
||||||
|
import org.elasticsearch.xpack.ql.plan.logical.OrderBy;
|
||||||
import org.elasticsearch.xpack.ql.plan.logical.UnresolvedRelation;
|
import org.elasticsearch.xpack.ql.plan.logical.UnresolvedRelation;
|
||||||
import org.elasticsearch.xpack.ql.tree.Source;
|
import org.elasticsearch.xpack.ql.tree.Source;
|
||||||
|
|
||||||
|
import static java.util.Collections.singletonList;
|
||||||
|
|
||||||
public class LogicalPlanTests extends ESTestCase {
|
public class LogicalPlanTests extends ESTestCase {
|
||||||
|
|
||||||
private final EqlParser parser = new EqlParser();
|
private final EqlParser parser = new EqlParser();
|
||||||
|
@ -25,7 +32,10 @@ public class LogicalPlanTests extends ESTestCase {
|
||||||
LogicalPlan fullQuery = parser.createStatement("process where process_name == 'net.exe'");
|
LogicalPlan fullQuery = parser.createStatement("process where process_name == 'net.exe'");
|
||||||
Expression fullExpression = expr("event_type == 'process' and process_name == 'net.exe'");
|
Expression fullExpression = expr("event_type == 'process' and process_name == 'net.exe'");
|
||||||
|
|
||||||
assertEquals(fullQuery, new Filter(Source.EMPTY, new UnresolvedRelation(Source.EMPTY, null, "", false, ""), fullExpression));
|
LogicalPlan filter = new Filter(Source.EMPTY, new UnresolvedRelation(Source.EMPTY, null, "", false, ""), fullExpression);
|
||||||
|
Order order = new Order(Source.EMPTY, new UnresolvedAttribute(Source.EMPTY, "timestamp"), OrderDirection.ASC, NullsPosition.FIRST);
|
||||||
|
LogicalPlan expected = new OrderBy(Source.EMPTY, filter, singletonList(order));
|
||||||
|
assertEquals(expected, fullQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testParameterizedEventQuery() {
|
public void testParameterizedEventQuery() {
|
||||||
|
@ -33,7 +43,9 @@ public class LogicalPlanTests extends ESTestCase {
|
||||||
LogicalPlan fullQuery = parser.createStatement("process where process_name == 'net.exe'", params);
|
LogicalPlan fullQuery = parser.createStatement("process where process_name == 'net.exe'", params);
|
||||||
Expression fullExpression = expr("myCustomEvent == 'process' and process_name == 'net.exe'");
|
Expression fullExpression = expr("myCustomEvent == 'process' and process_name == 'net.exe'");
|
||||||
|
|
||||||
assertEquals(fullQuery, new Filter(Source.EMPTY, new UnresolvedRelation(Source.EMPTY, null, "", false, ""), fullExpression));
|
LogicalPlan filter = new Filter(Source.EMPTY, new UnresolvedRelation(Source.EMPTY, null, "", false, ""), fullExpression);
|
||||||
|
Order order = new Order(Source.EMPTY, new UnresolvedAttribute(Source.EMPTY, "timestamp"), OrderDirection.ASC, NullsPosition.FIRST);
|
||||||
|
LogicalPlan expected = new OrderBy(Source.EMPTY, filter, singletonList(order));
|
||||||
|
assertEquals(expected, fullQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,9 @@
|
||||||
"event_type" : {
|
"event_type" : {
|
||||||
"type" : "keyword"
|
"type" : "keyword"
|
||||||
},
|
},
|
||||||
|
"timestamp" : {
|
||||||
|
"type" : "date"
|
||||||
|
},
|
||||||
"blob" : {
|
"blob" : {
|
||||||
"type" : "binary"
|
"type" : "binary"
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,9 @@
|
||||||
"event_type" : {
|
"event_type" : {
|
||||||
"type" : "keyword"
|
"type" : "keyword"
|
||||||
},
|
},
|
||||||
|
"timestamp" : {
|
||||||
|
"type" : "date"
|
||||||
|
},
|
||||||
"boolean_field" : {
|
"boolean_field" : {
|
||||||
"type" : "boolean"
|
"type" : "boolean"
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,9 @@
|
||||||
"event_type" : {
|
"event_type" : {
|
||||||
"type" : "keyword"
|
"type" : "keyword"
|
||||||
},
|
},
|
||||||
|
"timestamp" : {
|
||||||
|
"type" : "date"
|
||||||
|
},
|
||||||
"date" : {
|
"date" : {
|
||||||
"type" : "date"
|
"type" : "date"
|
||||||
},
|
},
|
||||||
|
|
|
@ -3,6 +3,9 @@
|
||||||
"event_type" : {
|
"event_type" : {
|
||||||
"type" : "keyword"
|
"type" : "keyword"
|
||||||
},
|
},
|
||||||
|
"timestamp" : {
|
||||||
|
"type" : "date"
|
||||||
|
},
|
||||||
"ip_addr" : {
|
"ip_addr" : {
|
||||||
"type" : "ip"
|
"type" : "ip"
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,9 @@
|
||||||
"event_type" : {
|
"event_type" : {
|
||||||
"type" : "keyword"
|
"type" : "keyword"
|
||||||
},
|
},
|
||||||
|
"timestamp" : {
|
||||||
|
"type" : "date"
|
||||||
|
},
|
||||||
"serial_event_id" : {
|
"serial_event_id" : {
|
||||||
"type" : "long"
|
"type" : "long"
|
||||||
},
|
},
|
||||||
|
|
|
@ -3,6 +3,9 @@
|
||||||
"event_type" : {
|
"event_type" : {
|
||||||
"type" : "keyword"
|
"type" : "keyword"
|
||||||
},
|
},
|
||||||
|
"timestamp" : {
|
||||||
|
"type" : "date"
|
||||||
|
},
|
||||||
"multi_field" : {
|
"multi_field" : {
|
||||||
"type" : "text",
|
"type" : "text",
|
||||||
"fields" : {
|
"fields" : {
|
||||||
|
|
|
@ -3,6 +3,9 @@
|
||||||
"event_type" : {
|
"event_type" : {
|
||||||
"type" : "keyword"
|
"type" : "keyword"
|
||||||
},
|
},
|
||||||
|
"timestamp" : {
|
||||||
|
"type" : "date"
|
||||||
|
},
|
||||||
"processes" : {
|
"processes" : {
|
||||||
"type" : "nested",
|
"type" : "nested",
|
||||||
"properties" : {
|
"properties" : {
|
||||||
|
|
|
@ -3,6 +3,9 @@
|
||||||
"event_type" : {
|
"event_type" : {
|
||||||
"type" : "keyword"
|
"type" : "keyword"
|
||||||
},
|
},
|
||||||
|
"timestamp" : {
|
||||||
|
"type" : "date"
|
||||||
|
},
|
||||||
"description_nodoc" : {
|
"description_nodoc" : {
|
||||||
"type" : "integer",
|
"type" : "integer",
|
||||||
"doc_values" : false
|
"doc_values" : false
|
||||||
|
|
|
@ -3,6 +3,9 @@
|
||||||
"event_type" : {
|
"event_type" : {
|
||||||
"type" : "keyword"
|
"type" : "keyword"
|
||||||
},
|
},
|
||||||
|
"timestamp" : {
|
||||||
|
"type" : "date"
|
||||||
|
},
|
||||||
"long_field" : {
|
"long_field" : {
|
||||||
"type" : "long"
|
"type" : "long"
|
||||||
},
|
},
|
||||||
|
|
|
@ -3,6 +3,9 @@
|
||||||
"event_type" : {
|
"event_type" : {
|
||||||
"type" : "keyword"
|
"type" : "keyword"
|
||||||
},
|
},
|
||||||
|
"timestamp" : {
|
||||||
|
"type" : "date"
|
||||||
|
},
|
||||||
"endgame" : {
|
"endgame" : {
|
||||||
"properties" : {
|
"properties" : {
|
||||||
"pid" : {
|
"pid" : {
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.sql.querydsl.container;
|
package org.elasticsearch.xpack.ql.querydsl.container;
|
||||||
|
|
||||||
import org.elasticsearch.xpack.ql.expression.Attribute;
|
import org.elasticsearch.xpack.ql.expression.Attribute;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.sql.querydsl.container;
|
package org.elasticsearch.xpack.ql.querydsl.container;
|
||||||
|
|
||||||
import org.elasticsearch.xpack.ql.expression.gen.script.ScriptTemplate;
|
import org.elasticsearch.xpack.ql.expression.gen.script.ScriptTemplate;
|
||||||
import org.elasticsearch.xpack.ql.expression.gen.script.Scripts;
|
import org.elasticsearch.xpack.ql.expression.gen.script.Scripts;
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.sql.querydsl.container;
|
package org.elasticsearch.xpack.ql.querydsl.container;
|
||||||
|
|
||||||
import org.elasticsearch.search.sort.SortOrder;
|
import org.elasticsearch.search.sort.SortOrder;
|
||||||
import org.elasticsearch.xpack.ql.expression.Order.NullsPosition;
|
import org.elasticsearch.xpack.ql.expression.Order.NullsPosition;
|
|
@ -18,11 +18,11 @@ import org.elasticsearch.search.sort.SortBuilder;
|
||||||
import org.elasticsearch.xpack.ql.execution.search.QlSourceBuilder;
|
import org.elasticsearch.xpack.ql.execution.search.QlSourceBuilder;
|
||||||
import org.elasticsearch.xpack.ql.expression.Attribute;
|
import org.elasticsearch.xpack.ql.expression.Attribute;
|
||||||
import org.elasticsearch.xpack.ql.expression.FieldAttribute;
|
import org.elasticsearch.xpack.ql.expression.FieldAttribute;
|
||||||
import org.elasticsearch.xpack.sql.querydsl.container.AttributeSort;
|
import org.elasticsearch.xpack.ql.querydsl.container.AttributeSort;
|
||||||
|
import org.elasticsearch.xpack.ql.querydsl.container.ScriptSort;
|
||||||
|
import org.elasticsearch.xpack.ql.querydsl.container.Sort;
|
||||||
import org.elasticsearch.xpack.sql.querydsl.container.QueryContainer;
|
import org.elasticsearch.xpack.sql.querydsl.container.QueryContainer;
|
||||||
import org.elasticsearch.xpack.sql.querydsl.container.ScoreSort;
|
import org.elasticsearch.xpack.sql.querydsl.container.ScoreSort;
|
||||||
import org.elasticsearch.xpack.sql.querydsl.container.ScriptSort;
|
|
||||||
import org.elasticsearch.xpack.sql.querydsl.container.Sort;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,10 @@ import org.elasticsearch.xpack.ql.expression.gen.pipeline.UnaryPipe;
|
||||||
import org.elasticsearch.xpack.ql.expression.gen.processor.Processor;
|
import org.elasticsearch.xpack.ql.expression.gen.processor.Processor;
|
||||||
import org.elasticsearch.xpack.ql.expression.gen.script.ScriptTemplate;
|
import org.elasticsearch.xpack.ql.expression.gen.script.ScriptTemplate;
|
||||||
import org.elasticsearch.xpack.ql.planner.ExpressionTranslators;
|
import org.elasticsearch.xpack.ql.planner.ExpressionTranslators;
|
||||||
|
import org.elasticsearch.xpack.ql.querydsl.container.AttributeSort;
|
||||||
|
import org.elasticsearch.xpack.ql.querydsl.container.ScriptSort;
|
||||||
|
import org.elasticsearch.xpack.ql.querydsl.container.Sort.Direction;
|
||||||
|
import org.elasticsearch.xpack.ql.querydsl.container.Sort.Missing;
|
||||||
import org.elasticsearch.xpack.ql.querydsl.query.Query;
|
import org.elasticsearch.xpack.ql.querydsl.query.Query;
|
||||||
import org.elasticsearch.xpack.ql.rule.Rule;
|
import org.elasticsearch.xpack.ql.rule.Rule;
|
||||||
import org.elasticsearch.xpack.ql.rule.RuleExecutor;
|
import org.elasticsearch.xpack.ql.rule.RuleExecutor;
|
||||||
|
@ -64,7 +68,6 @@ import org.elasticsearch.xpack.sql.querydsl.agg.GroupByNumericHistogram;
|
||||||
import org.elasticsearch.xpack.sql.querydsl.agg.GroupByValue;
|
import org.elasticsearch.xpack.sql.querydsl.agg.GroupByValue;
|
||||||
import org.elasticsearch.xpack.sql.querydsl.agg.LeafAgg;
|
import org.elasticsearch.xpack.sql.querydsl.agg.LeafAgg;
|
||||||
import org.elasticsearch.xpack.sql.querydsl.container.AggregateSort;
|
import org.elasticsearch.xpack.sql.querydsl.container.AggregateSort;
|
||||||
import org.elasticsearch.xpack.sql.querydsl.container.AttributeSort;
|
|
||||||
import org.elasticsearch.xpack.sql.querydsl.container.ComputedRef;
|
import org.elasticsearch.xpack.sql.querydsl.container.ComputedRef;
|
||||||
import org.elasticsearch.xpack.sql.querydsl.container.GlobalCountRef;
|
import org.elasticsearch.xpack.sql.querydsl.container.GlobalCountRef;
|
||||||
import org.elasticsearch.xpack.sql.querydsl.container.GroupByRef;
|
import org.elasticsearch.xpack.sql.querydsl.container.GroupByRef;
|
||||||
|
@ -74,9 +77,6 @@ import org.elasticsearch.xpack.sql.querydsl.container.MetricAggRef;
|
||||||
import org.elasticsearch.xpack.sql.querydsl.container.PivotColumnRef;
|
import org.elasticsearch.xpack.sql.querydsl.container.PivotColumnRef;
|
||||||
import org.elasticsearch.xpack.sql.querydsl.container.QueryContainer;
|
import org.elasticsearch.xpack.sql.querydsl.container.QueryContainer;
|
||||||
import org.elasticsearch.xpack.sql.querydsl.container.ScoreSort;
|
import org.elasticsearch.xpack.sql.querydsl.container.ScoreSort;
|
||||||
import org.elasticsearch.xpack.sql.querydsl.container.ScriptSort;
|
|
||||||
import org.elasticsearch.xpack.sql.querydsl.container.Sort.Direction;
|
|
||||||
import org.elasticsearch.xpack.sql.querydsl.container.Sort.Missing;
|
|
||||||
import org.elasticsearch.xpack.sql.querydsl.container.TopHitsAggRef;
|
import org.elasticsearch.xpack.sql.querydsl.container.TopHitsAggRef;
|
||||||
import org.elasticsearch.xpack.sql.session.EmptyExecutable;
|
import org.elasticsearch.xpack.sql.session.EmptyExecutable;
|
||||||
import org.elasticsearch.xpack.sql.type.SqlDataTypeConverter;
|
import org.elasticsearch.xpack.sql.type.SqlDataTypeConverter;
|
||||||
|
|
|
@ -10,9 +10,9 @@ import org.elasticsearch.search.aggregations.bucket.composite.CompositeAggregati
|
||||||
import org.elasticsearch.search.aggregations.bucket.composite.CompositeValuesSourceBuilder;
|
import org.elasticsearch.search.aggregations.bucket.composite.CompositeValuesSourceBuilder;
|
||||||
import org.elasticsearch.search.aggregations.bucket.filter.FiltersAggregationBuilder;
|
import org.elasticsearch.search.aggregations.bucket.filter.FiltersAggregationBuilder;
|
||||||
import org.elasticsearch.xpack.ql.expression.gen.script.ScriptTemplate;
|
import org.elasticsearch.xpack.ql.expression.gen.script.ScriptTemplate;
|
||||||
|
import org.elasticsearch.xpack.ql.querydsl.container.Sort.Direction;
|
||||||
import org.elasticsearch.xpack.ql.util.StringUtils;
|
import org.elasticsearch.xpack.ql.util.StringUtils;
|
||||||
import org.elasticsearch.xpack.sql.SqlIllegalArgumentException;
|
import org.elasticsearch.xpack.sql.SqlIllegalArgumentException;
|
||||||
import org.elasticsearch.xpack.sql.querydsl.container.Sort.Direction;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
|
@ -9,8 +9,8 @@ import org.elasticsearch.search.aggregations.bucket.composite.CompositeValuesSou
|
||||||
import org.elasticsearch.search.aggregations.bucket.composite.DateHistogramValuesSourceBuilder;
|
import org.elasticsearch.search.aggregations.bucket.composite.DateHistogramValuesSourceBuilder;
|
||||||
import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramInterval;
|
import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramInterval;
|
||||||
import org.elasticsearch.xpack.ql.expression.gen.script.ScriptTemplate;
|
import org.elasticsearch.xpack.ql.expression.gen.script.ScriptTemplate;
|
||||||
|
import org.elasticsearch.xpack.ql.querydsl.container.Sort.Direction;
|
||||||
import org.elasticsearch.xpack.sql.SqlIllegalArgumentException;
|
import org.elasticsearch.xpack.sql.SqlIllegalArgumentException;
|
||||||
import org.elasticsearch.xpack.sql.querydsl.container.Sort.Direction;
|
|
||||||
|
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
|
@ -8,8 +8,8 @@ package org.elasticsearch.xpack.sql.querydsl.agg;
|
||||||
import org.elasticsearch.search.aggregations.bucket.composite.CompositeValuesSourceBuilder;
|
import org.elasticsearch.search.aggregations.bucket.composite.CompositeValuesSourceBuilder;
|
||||||
import org.elasticsearch.search.aggregations.support.ValueType;
|
import org.elasticsearch.search.aggregations.support.ValueType;
|
||||||
import org.elasticsearch.xpack.ql.expression.gen.script.ScriptTemplate;
|
import org.elasticsearch.xpack.ql.expression.gen.script.ScriptTemplate;
|
||||||
|
import org.elasticsearch.xpack.ql.querydsl.container.Sort.Direction;
|
||||||
import org.elasticsearch.xpack.ql.type.DataTypes;
|
import org.elasticsearch.xpack.ql.type.DataTypes;
|
||||||
import org.elasticsearch.xpack.sql.querydsl.container.Sort.Direction;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ package org.elasticsearch.xpack.sql.querydsl.agg;
|
||||||
import org.elasticsearch.search.aggregations.bucket.composite.CompositeValuesSourceBuilder;
|
import org.elasticsearch.search.aggregations.bucket.composite.CompositeValuesSourceBuilder;
|
||||||
import org.elasticsearch.search.aggregations.bucket.composite.HistogramValuesSourceBuilder;
|
import org.elasticsearch.search.aggregations.bucket.composite.HistogramValuesSourceBuilder;
|
||||||
import org.elasticsearch.xpack.ql.expression.gen.script.ScriptTemplate;
|
import org.elasticsearch.xpack.ql.expression.gen.script.ScriptTemplate;
|
||||||
import org.elasticsearch.xpack.sql.querydsl.container.Sort.Direction;
|
import org.elasticsearch.xpack.ql.querydsl.container.Sort.Direction;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ package org.elasticsearch.xpack.sql.querydsl.agg;
|
||||||
import org.elasticsearch.search.aggregations.bucket.composite.CompositeValuesSourceBuilder;
|
import org.elasticsearch.search.aggregations.bucket.composite.CompositeValuesSourceBuilder;
|
||||||
import org.elasticsearch.search.aggregations.bucket.composite.TermsValuesSourceBuilder;
|
import org.elasticsearch.search.aggregations.bucket.composite.TermsValuesSourceBuilder;
|
||||||
import org.elasticsearch.xpack.ql.expression.gen.script.ScriptTemplate;
|
import org.elasticsearch.xpack.ql.expression.gen.script.ScriptTemplate;
|
||||||
import org.elasticsearch.xpack.sql.querydsl.container.Sort.Direction;
|
import org.elasticsearch.xpack.ql.querydsl.container.Sort.Direction;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GROUP BY key for fields or scripts.
|
* GROUP BY key for fields or scripts.
|
||||||
|
|
|
@ -17,7 +17,7 @@ import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
import static org.elasticsearch.search.aggregations.AggregationBuilders.topHits;
|
import static org.elasticsearch.search.aggregations.AggregationBuilders.topHits;
|
||||||
import static org.elasticsearch.xpack.sql.querydsl.container.Sort.Missing.LAST;
|
import static org.elasticsearch.xpack.ql.querydsl.container.Sort.Missing.LAST;
|
||||||
|
|
||||||
public class TopHitsAgg extends LeafAgg {
|
public class TopHitsAgg extends LeafAgg {
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
package org.elasticsearch.xpack.sql.querydsl.container;
|
package org.elasticsearch.xpack.sql.querydsl.container;
|
||||||
|
|
||||||
import org.elasticsearch.xpack.ql.expression.function.aggregate.AggregateFunction;
|
import org.elasticsearch.xpack.ql.expression.function.aggregate.AggregateFunction;
|
||||||
|
import org.elasticsearch.xpack.ql.querydsl.container.Sort;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.sql.querydsl.container;
|
package org.elasticsearch.xpack.sql.querydsl.container;
|
||||||
|
|
||||||
|
import org.elasticsearch.xpack.ql.querydsl.container.Sort;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public class GroupingFunctionSort extends Sort {
|
public class GroupingFunctionSort extends Sort {
|
||||||
|
|
|
@ -20,6 +20,7 @@ import org.elasticsearch.xpack.ql.expression.FieldAttribute;
|
||||||
import org.elasticsearch.xpack.ql.expression.function.scalar.ScalarFunction;
|
import org.elasticsearch.xpack.ql.expression.function.scalar.ScalarFunction;
|
||||||
import org.elasticsearch.xpack.ql.expression.gen.pipeline.ConstantInput;
|
import org.elasticsearch.xpack.ql.expression.gen.pipeline.ConstantInput;
|
||||||
import org.elasticsearch.xpack.ql.expression.gen.pipeline.Pipe;
|
import org.elasticsearch.xpack.ql.expression.gen.pipeline.Pipe;
|
||||||
|
import org.elasticsearch.xpack.ql.querydsl.container.Sort;
|
||||||
import org.elasticsearch.xpack.ql.querydsl.query.BoolQuery;
|
import org.elasticsearch.xpack.ql.querydsl.query.BoolQuery;
|
||||||
import org.elasticsearch.xpack.ql.querydsl.query.MatchAll;
|
import org.elasticsearch.xpack.ql.querydsl.query.MatchAll;
|
||||||
import org.elasticsearch.xpack.ql.querydsl.query.NestedQuery;
|
import org.elasticsearch.xpack.ql.querydsl.query.NestedQuery;
|
||||||
|
|
|
@ -5,6 +5,9 @@
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.sql.querydsl.container;
|
package org.elasticsearch.xpack.sql.querydsl.container;
|
||||||
|
|
||||||
|
import org.elasticsearch.xpack.ql.querydsl.container.ScriptSort;
|
||||||
|
import org.elasticsearch.xpack.ql.querydsl.container.Sort;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public class ScoreSort extends Sort {
|
public class ScoreSort extends Sort {
|
||||||
|
|
|
@ -19,17 +19,17 @@ import org.elasticsearch.xpack.ql.expression.AttributeMap;
|
||||||
import org.elasticsearch.xpack.ql.expression.Expression;
|
import org.elasticsearch.xpack.ql.expression.Expression;
|
||||||
import org.elasticsearch.xpack.ql.expression.FieldAttribute;
|
import org.elasticsearch.xpack.ql.expression.FieldAttribute;
|
||||||
import org.elasticsearch.xpack.ql.expression.ReferenceAttribute;
|
import org.elasticsearch.xpack.ql.expression.ReferenceAttribute;
|
||||||
|
import org.elasticsearch.xpack.ql.querydsl.container.AttributeSort;
|
||||||
|
import org.elasticsearch.xpack.ql.querydsl.container.Sort.Direction;
|
||||||
|
import org.elasticsearch.xpack.ql.querydsl.container.Sort.Missing;
|
||||||
import org.elasticsearch.xpack.ql.querydsl.query.MatchQuery;
|
import org.elasticsearch.xpack.ql.querydsl.query.MatchQuery;
|
||||||
import org.elasticsearch.xpack.ql.tree.Source;
|
import org.elasticsearch.xpack.ql.tree.Source;
|
||||||
import org.elasticsearch.xpack.ql.type.KeywordEsField;
|
import org.elasticsearch.xpack.ql.type.KeywordEsField;
|
||||||
import org.elasticsearch.xpack.sql.expression.function.Score;
|
import org.elasticsearch.xpack.sql.expression.function.Score;
|
||||||
import org.elasticsearch.xpack.sql.querydsl.agg.AvgAgg;
|
import org.elasticsearch.xpack.sql.querydsl.agg.AvgAgg;
|
||||||
import org.elasticsearch.xpack.sql.querydsl.agg.GroupByValue;
|
import org.elasticsearch.xpack.sql.querydsl.agg.GroupByValue;
|
||||||
import org.elasticsearch.xpack.sql.querydsl.container.AttributeSort;
|
|
||||||
import org.elasticsearch.xpack.sql.querydsl.container.QueryContainer;
|
import org.elasticsearch.xpack.sql.querydsl.container.QueryContainer;
|
||||||
import org.elasticsearch.xpack.sql.querydsl.container.ScoreSort;
|
import org.elasticsearch.xpack.sql.querydsl.container.ScoreSort;
|
||||||
import org.elasticsearch.xpack.sql.querydsl.container.Sort.Direction;
|
|
||||||
import org.elasticsearch.xpack.sql.querydsl.container.Sort.Missing;
|
|
||||||
|
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
Loading…
Reference in New Issue