Support named query scores in Hit.matchedQueries() - #2098
Conversation
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>
# Conflicts: # CHANGELOG.md
Signed-off-by: Sotaro Hikita <bering1814@gmail.com>
# Conflicts: # CHANGELOG.md
| private Map<String, InnerHitsResult> innerHits; | ||
| @Nullable | ||
| private JsonData matchedQueries; | ||
| private Map<String, Double> matchedQueries; |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
@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.
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.