-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Long range query support #3299
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
Long range query support #3299
Conversation
Hi @annashlyak, we have found your signature in our records, but it seems like you have signed with a different e-mail than the one used in yout Git commit. Can you please add both of these e-mails into your Github profile (they can be hidden), so we can match your e-mails to your Github profile? |
Hi @karmi, I have added email to my profile |
Thanks for the PR @annashlyak 😄 this LGTM. |
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 PR @annashlyak! I've left a couple of small comments, when you have a chance to take a look
|
||
var isNumeric = !jo.Properties().Any(p => p.Name == "format" || p.Name == "time_zone") |
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 it possible to refactor this to remove the duplicated code within isLong
and isNumeric
checks. It may be possible to reduce down to one enumeration/iteration of jo.Properties
to determine IRangeQuery
@@ -79,7 +79,9 @@ private void Write(string queryType, Field field = null) | |||
|
|||
public virtual void Visit(INumericRangeQuery query) => Write("numeric_range"); | |||
|
|||
public virtual void Visit(ITermRangeQuery query) => Write("term_range"); | |||
public virtual void Visit(ILongRangeQuery query) => Write("numeric_range"); |
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.
long_range
?
would you like me to take another look at the PR @annashlyak - is it ready to review again? |
@russcam yes, you can watch review again |
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 @annashlyak, I've left a comment to simplify determining the range query.
Let me know what you think 🙂
var nameIsValid = !jo.Properties().Any(p => p.Name == "format" || p.Name == "time_zone"); | ||
|
||
var isLong = nameIsValid && CheckType(jo, JTokenType.Integer); | ||
var isNumeric = nameIsValid && CheckType(jo, JTokenType.Float); |
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 this can be simplified further.
For isNumeric
and DateRangeQuery cases, CheckType
will end up being called twice. It looks like it should be possible to enumerate/iterate over jo.Properties()
once and determine from the existence of "format", "time_zone" or token type, which IRangeQuery
it is. I was thinking something like
private static IRangeQuery GetRangeQuery(JsonSerializer serializer, JObject jo)
{
foreach (var property in jo.Properties())
{
if (property.Name == "format" || property.Name == "time_zone")
return FromJson.ReadAs<DateRangeQuery>(jo.CreateReader(), serializer);
if (_rangeKeys.Contains(property.Name))
{
if (property.Value.Type == JTokenType.Integer)
return FromJson.ReadAs<LongRangeQuery>(jo.CreateReader(), serializer);
if (property.Value.Type == JTokenType.Float)
return FromJson.ReadAs<NumericRangeQuery>(jo.CreateReader(), serializer);
return FromJson.ReadAs<DateRangeQuery>(jo.CreateReader(), serializer);
}
}
}
what do you think?
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.
Yes, thank you. LGTM. "format" and "time_zone" checks must be done for all properties in jo. When we check for a type, we can not immediately return the result, because LongRange is used, if there was no property of type float, but there was a property of type int. However, we can iterate once and I think that the code will looks better.
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.
Left some additional comments @annashlyak. Let me know your thoughts
@@ -37,36 +37,30 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist | |||
|
|||
private static IRangeQuery GetRangeQuery(JsonSerializer serializer, JObject jo) | |||
{ | |||
var nameIsValid = !jo.Properties().Any(p => p.Name == "format" || p.Name == "time_zone"); | |||
IRangeQuery fq = FromJson.ReadAs<DateRangeQuery>(jo.CreateReader(), serializer); |
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.
At this point, we don't know if the range query is one on date fields. I think assigning null
is more appropriate
IRangeQuery fq = null;
and deserializing to DateRangeQuery
only when it is known that the query is one on date 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.
Earlier we deserialize to DateRangeQuery always when check for numeric Type was false. I think that we can just not declare fq.
if (_rangeKeys.Contains(property.Name)) | ||
{ | ||
if (property.Value.Type == JTokenType.Float) | ||
isNumeric = true; |
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 any one of the range properties is a float
JSON type, then I think it's safe to return NumericRangeQuery
query here.
The assumption that can't be made, if I've understood correctly, is that we can't rule out NumericRangeQuery
if a range property is an integer
JSON type until we've seen all the range properties i.e. put another way, we can't be sure to return LongRangeQuery
until we've seen all of the range properties, and observed that they are all integer
JSON types.
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.
Earlier was check !jo.Properties().Any(p => p.Name == "format" || p.Name == "time_zone") It is the same as jo.Properties().All(p => p.Name != "format" && p.Name != "time_zone"). So, we have to done this for all properties and I dont want return here NumericRangeQuery
85821ac
to
958118c
Compare
This looks great, @annashlyak! Thank you for your effort 👍 |
add LongRangeQuery to handle range queries on long numeric field types. (cherry picked from commit 69733ea)
Hello, everybody,
I want to make range queries that correctly work with long type. So, I have added support of long range query.
Small test to demonstrate trouble that I want to solve .
We want to work with timestamps that are long type:
converts numbers to double type:
and loses precision.
Elasticsearch himself is able to make such requests, but in NEST this functionality is missed.
I will be grateful if you merge my pull request and I'm ready to discuss my decision.