-
Notifications
You must be signed in to change notification settings - Fork 25.6k
EQL: Add Head/Tail pipe support #58536
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure thing. Thanks!
astefan
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Left some comments.
| private final HitExtractor tiebreakerExtractor; | ||
|
|
||
| // search after markers | ||
| private Object[] startMarker; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe name these with the plural variant, since they are arrays?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the tiebreaker is not set, why still logging the square brackets?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To indicate there is no tiebreaker - I find the message more consistent to be [..][] vs [..]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Myself, I wouldn't mind to have [] when there is no tiebreaker.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about specifying that there is no tiebreaker? (ie [...][no tiebreaker])
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's quite verbose...
...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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this being used anywhere?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor: code formatting for consistency:
| Attribute tiebreaker, OrderDirection direction) { | |
| Attribute tiebreaker, | |
| OrderDirection direction) { |
| this.attributes = attributes; | ||
| this.trackHits = trackHits; | ||
| this.includeFrozen = includeFrozen; | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor: empty line
Introduce pipe support, in particular head and tail
(which can also be chained).
Replaces #58326