-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Implement custom RangeQuery interface to support Elasticsearch v9 #7358
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
Implement custom RangeQuery interface to support Elasticsearch v9 #7358
Conversation
Signed-off-by: Mohammed Shuraih <shuraih15@gmail.com>
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #7358 +/- ##
==========================================
+ Coverage 96.46% 96.48% +0.01%
==========================================
Files 376 377 +1
Lines 22957 22989 +32
==========================================
+ Hits 22146 22181 +35
+ Misses 613 611 -2
+ Partials 198 197 -1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
…anstore/reader_test.go Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com> Signed-off-by: shuraih775 <74284337+shuraih775@users.noreply.github.com>
Signed-off-by: Mohammed Shuraih <shuraih15@gmail.com>
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 you think this solves the v9 support problem then please add v9 into integration tests, to validate this change
Signed-off-by: Mohammed Shuraih <shuraih15@gmail.com>
@@ -1134,8 +1132,8 @@ func TestSpanReader_buildStartTimeQuery(t *testing.T) { | |||
expected := make(map[string]any) | |||
json.Unmarshal([]byte(expectedStr), &expected) | |||
// We need to do this because we cannot process a json into uint64. |
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.
do we know what this comment refers to? "to do this" - do what?
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 do this" refers to replacing the float64
values that json.Unmarshal
produces with uint64
, because the actual query output uses uint64
(e.g., microseconds for durations). This ensures the test compares values with matching types.
json.Unmarshal
parses all numeric values asfloat64
by default when decoding intointerface{}
.
We convert to uint64
because the function under test internally uses model.TimeAsEpochMicroseconds
, which returns a uint64
:
Source — TimeAsEpochMicroseconds
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.
so we unmarshal a string that contains two "expected" numbers but then override those numbers with other values. Why not just construct the expected map directly? What's the value of unmarshalling the string?
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.
The original test used JSON unmarshalling to handle nested fields like include_lower/include_upper
. In the new query, that's no longer needed, but I kept the style consistent with the existing tests. Happy to simplify it if preferred.
name string | ||
gt any | ||
gte any | ||
lt any | ||
lte any | ||
timeZone string | ||
boost *float64 | ||
queryName string | ||
format string | ||
relation string |
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.
Q: why store these values as fields instead of adding them directly to the map right away? It would reduce the amount of code
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.
This RangeQuery
implementation follows the elastic.Query
interface format:
type Query interface {
// Source returns the JSON-serializable query request.
Source() (interface{}, error)
}
This design is intentional and critical for compatibility with the existing Jaeger codebase. Many parts of Jaeger — such as query builders and Elasticsearch readers — expect all queries to satisfy the elastic.Query interface.
If we were to remove the Source()
method or replace this with a direct map[string]any
-style implementation, it would break the entire pipeline wherever elastic.Query is used. Calls like query.Source()
would fail at compile time.
Moreover, this struct-based implementation is modeled after the previously used olivere/elastic/v7
library. By keeping the method signatures (.Gte(), .Lte(), etc.)
and Source()
behavior consistent, we ensure minimal refactoring and preserve the existing query composition logic.
So while a direct map-based query might look simpler in isolation, it’s not viable in this context. Our approach ensures:
- Full compatibility with the elastic.Query interface
- Minimal changes to existing logic
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 am not suggesting changing the interface, but changing implementation where
func (q *RangeQuery) Lte(val any) *RangeQuery {
q.lte = val
return q
}
becomes
func (q *RangeQuery) Lte(val any) *RangeQuery {
q.params["lte"] = val
return q
}
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 for the clarification! You're right—refactoring to directly update params in the setters would simplify Source() and reduce redundancy. I’ll go ahead and refactor it that way.
Signed-off-by: Mohammed Shuraih <shuraih15@gmail.com>
Pull Request is not mergeable
f0417ca
Which problem is this PR solving?
RangeQuery
structure from theolivere/elastic
client.olivere/elastic/v7.RangeQuery
with a custom implementation.Description of the changes
RangeQuery
interface underinternal/storage/elasticsearch/query
.include_lower
,include_upper
,from
, andto
.RangeQuery
with the new implementation._search
API.How was this change tested?
RangeQuery
implementation.docker.elastic.co/elasticsearch/elasticsearch:9.0.3
).Checklist
jaeger
:make lint test
jaeger-ui
:npm run lint
andnpm run test