I need to write one range query with different condition base
await _elasticClient.SearchAsync<T>(s => s
.Index(IndexName)
.From(From)
.Size(Size)
.Aggregations(ag => ag
.Cardinality("SumName", ca => ca.Field("CardinalField")))
.Query(q => q
.Bool(b => b
.Must(m => m
.QueryString(qs => qs .Fields("FieldNames").Query("FieldValue")),
m => m.Terms(tf => tf
.Field("TermField")
.Terms("TermFeildVal")),
m => m.Range(ra => ra.Field("RangeField").GreaterThanOrEquals("RangeVal")))))
).ConfigureAwait(false);
How can I use GreaterThanOrEquals, GreaterThan, LessThanOrEquals & GreaterThan on the basis of my input string, e.g., if someone wants with gte, use GreaterThanOrEquals, if they want lte, use LessThanOrEquals, etc.?
Like
await _elasticClient.SearchAsync<T>(s => s
.Index(objFeasibilityRangeVM.IndexName)
.From(objFeasibilityRangeVM.From)
.Size(objFeasibilityRangeVM.Size)
.Aggregations(ag => ag
.Cardinality(objFeasibilityRangeVM.SumName, ca => ca.Field(objFeasibilityRangeVM.CardinalField)))
.Query(q => q
.Bool(b => b
.Must(m => m
.QueryString(qs => qs
.Fields(objFeasibilityRangeVM.FieldNames).Query(objFeasibilityRangeVM.FieldValue)),
m => m.Terms(tf => tf
.Field(objFeasibilityRangeVM.TermField)
.Terms(objFeasibilityRangeVM.TermFeildVal)),
m => m.Range(ra => ra.Field(objFeasibilityRangeVM.RangeField)
FieldValue == "gte"?
.GreaterThanOrEquals(RangeVal)
: .LessThanOrEquals(RangeVal)
))))
).ConfigureAwait(false);
CodePudding user response:
One option could be to move range part into method like this
QueryContainer Range(string condition)
{
return condition == "gte"
? new NumericRangeQuery { Field = "RangeField", GreaterThanOrEqualTo = 1 }
: new NumericRangeQuery { Field = "RangeField", LessThanOrEqualTo = 1 };
}
and then your query becomes something like
await _elasticClient.SearchAsync<T>(s => s
.Index(IndexName)
.From(From)
.Size(Size)
.Aggregations(ag => ag
.Cardinality("SumName", ca => ca.Field("CardinalField")))
.Query(q => q
.Bool(b => b
.Must(m => m
.QueryString(qs => qs.Fields("FieldNames").Query("FieldValue")),
m => m.Terms(tf => tf
.Field("TermField")
.Terms("TermFeildVal")),
_ => Range("gte"))))
).ConfigureAwait(false);
With second idea you could inline your logic like below using the fact that in case to
/ from
values are null
NEST will omit those in generated query to Elasticsearch
var searchResponse = await client.SearchAsync<object>(s => s
.Index("test")
.From(0)
.Size(10)
.Aggregations(ag => ag
.Cardinality("SumName", ca => ca.Field("CardinalField")))
.Query(q => q
.Bool(b => b
.Must(m => m
.QueryString(qs => qs.Fields("FieldNames").Query("FieldValue")),
m => m.Terms(tf => tf
.Field("TermField")
.Terms("TermFeildVal")),
m =>
{
double? gtValue = null;
double? ltValue = null;
if (FieldValue == "gte")
{
gtValue = 1;
}
if (FieldValue == "lte")
{
ltValue = 2;
}
return m.Range(ra => ra.Field("RangeField").LessThanOrEquals(ltValue).GreaterThanOrEquals(gtValue));
})))
);