EQL: Add Head/Tail pipe support#58536
Conversation
Introduce pipe support, in particular head and tail (which can also be chained).
|
Pinging @elastic/es-ql (:Query Languages/EQL) |
|
The main idea behind this PR is to support head/tail through a limit (w/ offset). Further more when dealing with tail, data needs to be returned in descending format however since ES does not offer a The code can be further polished, in particular the query side and progression of the keys (so its handling doesn't leak inside the |
Add Head and Tail to simplify verification and future identification of said nodes.
| 1607252647000 | ||
| ] | ||
| ], | ||
| "fields": { |
There was a problem hiding this comment.
@jrodewig is there a way to ignore the "fields" field? This data is used internally and it might be that in the future, we'll remove it from the final response (so only _source is included).
There was a problem hiding this comment.
You can use the filter_path query param to exclude fields from the output.
You can add the query param using a //TEST comment so it's not visible to users.
This should fail gracefully. The request won't return an error if fields is later removed from the response.
Here's an example with a basic query:
[source,console]
----
GET /sec_logs/_eql/search
{
"query": """
process where process.name == "cmd.exe"
"""
}
----
// TEST[s/search/search\?filter_path\=\-\*\.events\.\*fields/]
A sequence query will need to use a different filter because the response format is different.
[source,console]
----
GET /my_index/_eql/search
{
"query": """
sequence by agent.id
[ file where file.name == "cmd.exe" and agent.id != "my_user" ]
[ process where stringContains(process.path, "regsvr32") ]
"""
}
----
// TEST[s/search/search\?filter_path\=\-\*\.sequences\.events\.\*fields/]
There was a problem hiding this comment.
For some reason this didn't seem to work consistently so I left things in a bit of a mixed state, namely the fields tag is still in there but I also added the TESTRESPONSE; the idea being that the user should not depend on whether fields (or even sort) are in the response.
Can you please take a look at it after this PR gets merged?
astefan
left a comment
There was a problem hiding this comment.
LGTM. Left some comments.
| private final HitExtractor tiebreakerExtractor; | ||
|
|
||
| // search after markers | ||
| private Object[] startMarker; |
There was a problem hiding this comment.
Maybe name these with the plural variant, since they are arrays?
There was a problem hiding this comment.
I had them as such but in case of a timestamp there's only one marker. Plus the fact that it's one or multiple fields is an implementation detail in the end.
Hence why talking a marker as an entity (which currently happens to be an array of objects) seems better.
| tiebreaker = tiebreaker(hit); | ||
| } | ||
|
|
||
| return tiebreaker != null ? new Object[] { timestamp, tiebreaker } : new Object[] { timestamp }; |
There was a problem hiding this comment.
Since the markers can only be a combination of timestamp and tiebreaker OR only the timestamp, maybe abstract these two variants away in a TiebreakerMarker and TimestampMarker or something around these lines?
There was a problem hiding this comment.
I think the whole marker bit can be encapsulated in the Criterion itself, I plan to revisit this when working on the pagination.
|
|
||
| @Override | ||
| public String toString() { | ||
| return key + "[" + timestamp + "][" + (tiebreaker != null ? Objects.toString(tiebreaker) : "") + "]"; |
There was a problem hiding this comment.
If the tiebreaker is not set, why still logging the square brackets?
There was a problem hiding this comment.
To indicate there is no tiebreaker - I find the message more consistent to be [..][] vs [..]
There was a problem hiding this comment.
Myself, I wouldn't mind to have [] when there is no tiebreaker.
There was a problem hiding this comment.
How about specifying that there is no tiebreaker? (ie [...][no tiebreaker])
...lugin/eql/src/main/java/org/elasticsearch/xpack/eql/execution/assembler/SequenceRuntime.java
Outdated
Show resolved
Hide resolved
...lugin/eql/src/main/java/org/elasticsearch/xpack/eql/execution/assembler/SequenceRuntime.java
Outdated
Show resolved
Hide resolved
x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/optimizer/Optimizer.java
Outdated
Show resolved
Hide resolved
x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/parser/LogicalPlanBuilder.java
Outdated
Show resolved
Hide resolved
x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/parser/LogicalPlanBuilder.java
Show resolved
Hide resolved
| } | ||
| } | ||
|
|
||
| abstract static class QueryFoldingRule<SubPlan extends UnaryExec> extends FoldingRule<SubPlan> { |
There was a problem hiding this comment.
Is this being used anywhere?
There was a problem hiding this comment.
Thanks. Used it for the existing rules
x-pack/plugin/eql/src/test/java/org/elasticsearch/xpack/eql/optimizer/OptimizerTests.java
Show resolved
Hide resolved
matriv
left a comment
There was a problem hiding this comment.
Looks good overall, left some minor comments, but additionally can we have some unit tests for the new optimizer rules: SortByLimit, PushDownOrderBy and SkipQueryOnLimitZero? (unless I missed something :) )
|
|
||
| @Override | ||
| public String toString() { | ||
| return key + "[" + timestamp + "][" + (tiebreaker != null ? Objects.toString(tiebreaker) : "") + "]"; |
There was a problem hiding this comment.
Myself, I wouldn't mind to have [] when there is no tiebreaker.
x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/parser/LogicalPlanBuilder.java
Outdated
Show resolved
Hide resolved
| Attribute timestamp, | ||
| Attribute tiebreaker) { | ||
| this(source, combine(matches, until), combine(keys, singletonList(untilKeys)), timestamp, tiebreaker); | ||
| Attribute tiebreaker, OrderDirection direction) { |
There was a problem hiding this comment.
Minor: code formatting for consistency:
| Attribute tiebreaker, OrderDirection direction) { | |
| Attribute tiebreaker, | |
| OrderDirection direction) { |
| this.attributes = attributes; | ||
| this.trackHits = trackHits; | ||
| this.includeFrozen = includeFrozen; | ||
|
|
Introduce pipe support, in particular head and tail
(which can also be chained).
Replaces #58326