Skip to content

Support named query scores in Hit.matchedQueries() - #2098

Open
lawofcycles wants to merge 4 commits into
opensearch-project:mainfrom
lawofcycles:matched-queries-score
Open

Support named query scores in Hit.matchedQueries()#2098
lawofcycles wants to merge 4 commits into
opensearch-project:mainfrom
lawofcycles:matched-queries-score

Conversation

@lawofcycles

Copy link
Copy Markdown

Description

This change lets the client retrieve named query scores through the typed API. Hit.matchedQueries() is now generated as Map<String, Double> mapping each named query to its score, and include_named_queries_score is sent as a query parameter so the server returns the scored map.

On the response side, a schema driven rule in the code generator detects the oneOf of a string array and a scalar value map and maps it to a typed map. The deserializer reads the object form as name to score and the array form as names with null values. This replaces the generic JsonData fallback that the polymorphic matched_queries schema previously produced. The detection is generic and, against the current specification, applies only to Hit.matched_queries.

On the request side, include_named_queries_score is emitted as a query parameter. The request body property is ignored in the code generator on purpose, because the server enables the scored map rendering only from the query parameter. Sending the flag in the request body returns names without scores. See opensearch-project/OpenSearch#22689 for that server behavior.

matched_queries is typed directly instead of adding a separate scores field. This is a breaking change scoped to the 4.0 line, where matched_queries was already exposed as JsonData rather than List, so no existing typed usage breaks.

Issues Resolved

Closes #1805

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.

matched_queries is now generated as Map<String, Double> instead of the
generic JsonData fallback. A schema driven rule in the code generator
detects the oneOf of a string array and a scalar value map and maps it to
a typed map. The deserializer reads the object form as name to score and
the array form as names with null values.

include_named_queries_score is now sent as a query parameter rather than
in the request body. The server enables the scored map rendering only from
the query parameter, so sending the flag in the body returns names without
scores. The request body property is ignored in the code generator so the
generated client emits the query parameter. See
opensearch-project/OpenSearch#22689 for the
server behavior.

Adds MatchedQueriesTest covering the array and object forms.

Signed-off-by: Sotaro Hikita <bering1814@gmail.com>
Signed-off-by: Sotaro Hikita <bering1814@gmail.com>
private Map<String, InnerHitsResult> innerHits;
@Nullable
private JsonData matchedQueries;
private Map<String, Double> matchedQueries;

@reta reta Aug 12, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks @lawofcycles , to be fair, I have some doubts this is the approach we should take: matchedQueries is either a map (when named) or array, however we just flush it out as a map with null scores - not very intuitive and asking for bug reports. I will spend a bit more time looking into other options, if any, thank you.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

@reta Fair concern on the null valued map. I see two typed shapes that avoid it.

One is a TaggedUnion of the array and map forms, in the spirit of SourceConfig or FieldValue, bound through withMappedType. The other keeps matchedQueries() as List and adds a separate matchedQueryScores() as Map<String, Double> that is filled only when scores are requested.

The split field reads a little more naturally for callers, but the union fits the existing code generation much better, since it reuses the withMappedType path with no changes to the object templates, while the split field would need one wire key to populate two fields on both read and write. I am leaning toward the union for that reason. Let me know which direction you prefer, or if you have another shape in mind.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE] Support include_named_queries_score to parsed scores of named queries

2 participants