Build aggregation responses from execution results - #22526
Conversation
Convert flat per-granularity execution results into the client's nested aggregation response using the original request as template. Co-authored-by: Varun <varunsm@amazon.com> Signed-off-by: Sachin Sriramagiri <srirasac@amazon.com>
PR Reviewer Guide 🔍(Review updated until commit 85dcbf4)Here are some key observations to aid the review process:
|
PR Code Suggestions ✨Latest suggestions up to 85dcbf4 Explore these optional code suggestions:
Previous suggestionsSuggestions up to commit f030201
Suggestions up to commit 7017942
Suggestions up to commit 843ee01
Suggestions up to commit 518338d
Suggestions up to commit c6a65de
|
|
❌ Gradle check result for c6a65de: FAILURE Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
Exclude SQL NULL groups from terms buckets (legacy parity), resolve granularity keys from the aggregate's input row type, use NUL key separator, null-safe toDouble error message. Signed-off-by: Sachin Sriramagiri <srirasac@amazon.com>
|
Persistent review updated to latest commit 518338d |
|
❌ Gradle check result for 518338d: FAILURE Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
Key aggregation results by nesting-order group fields so sibling trees over the same field set no longer collide. Signed-off-by: Sachin Sriramagiri <srirasac@amazon.com>
|
Persistent review updated to latest commit 843ee01 |
|
❌ Gradle check result for 843ee01: TIMEOUT Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
| @Override | ||
| protected void doExecute(Task task, SearchRequest request, ActionListener<SearchResponse> listener) { | ||
| threadPool.executor(ThreadPool.Names.SEARCH).execute(() -> { | ||
| final long startTime = System.currentTimeMillis(); |
There was a problem hiding this comment.
Lets use System.nanoTime() for latency calculations
| } | ||
|
|
||
| Map<String, Integer> colIndex = buildColumnIndex(result); | ||
| List<Object[]> filteredRows = filterRows(rows, colIndex, parentKeyFilter); |
There was a problem hiding this comment.
At every recursion, we again filter through the complete list of rows. Can we instead index them in a map so that iteration becomes linear even when recursed multiple times?
(We can add TODO for that and optimize in follow up PR)
There was a problem hiding this comment.
added a TODO for now. Will raise a separate PR for this
| @Override | ||
| public InternalAggregation toInternalAggregation(String name, Object value) { | ||
| if (value == null) { | ||
| return new InternalAvg(name, 0.0, 0, DocValueFormat.RAW, null); |
There was a problem hiding this comment.
We are passing here null for metadata parameter public InternalAvg(String name, double sum, long count, DocValueFormat format, Map<String, Object> metadata). Do we need to pass the metadata values as well and process that to be consistent with OpenSearch?
| Map<String, Integer> colIndex = buildColumnIndex(result); | ||
| Integer colIdx = colIndex.get(agg.getName()); | ||
|
|
||
| if (colIdx == null) { |
There was a problem hiding this comment.
If the metric's column is missing from the result, this silently returns an empty metric , but a missing column means the plan/metadata invariant broke, and the analogous cases (groupRowsByKeys missing group column, buildBucket missing count column) throw ConversionException. Should this throw too, so pipeline bugs surface instead of rendering as "value": null?
- Use nanoTime for latency - Echo user-supplied meta in aggregation responses - Throw when a metric column is missing from results - Added TODO to index rows instead of re-filtering per recursion Signed-off-by: Sachin Sriramagiri <srirasac@amazon.com>
|
Persistent review updated to latest commit 7017942 |
Sort buckets by each aggregation's requested order, drop buckets below min_doc_count, truncate to size, and report truncated counts as sum_other_doc_count. Signed-off-by: Sachin Sriramagiri <srirasac@amazon.com>
|
Persistent review updated to latest commit f030201 |
The lookup is invariant per granularity result. Signed-off-by: Sachin Sriramagiri <srirasac@amazon.com>
|
Persistent review updated to latest commit 85dcbf4 |
|
❌ Gradle check result for 85dcbf4: FAILURE Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
nssuresh2007
left a comment
There was a problem hiding this comment.
LGTM. Just a nitpick comment
| * AND distinct keys. Re-deriving the key from the plan's group bit set would yield schema order | ||
| * instead, forcing an order-insensitive (sorted) key under which such siblings collide. | ||
| */ | ||
| public final class AggregationResponseBuilder { |
There was a problem hiding this comment.
I think for pipeline aggregations, where we need to do post processing on the response we would still need some handling which is not covered in this PR, is that understanding correct?
If yes, please add a TODO for the same.
Convert flat per-granularity execution results into the client's nested aggregation response using the original request as template.
Description
Converts analytics engine execution results into OpenSearch InternalAggregations format, enabling aggregation responses in the DSL query executor. Supersedes #21346.
Changes
Verified end to end on a live composite index: terms + metrics, filtered global metrics, and two-level nested aggregations return correct legacy-shaped responses.
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.