I have the following model
public class Ticket
{
public string Id { get; set; }
public string Question { get; set; }
public DateTime CreateDate { get; set; }
public DateTime ClosedDate { get; set; }
public int Votes { get; set; }
}
I'm using ElasticSearch Nest client to search for tickets where any field contains a certain text within a date range.
I tried the following:
var result = client.Search<Ticket>(
s => s.Query(q =>
q.Bool(b =>
b.Must(ms => ms.QueryString(qs => qs.Query(term)))
.Filter(f =>
f.Bool(bb =>
bb.Must(ms => ms.DateRange(dr => dr.GreaterThanOrEquals(from).LessThanOrEquals(to))
))))));
It returns all tickets regardless of the time specified.
It also only search for complete word while I want to search for any part of the word in the text.
Any ideas?
The DateRange
query requires a Field
value for the field in Elasticsearch to run against. When a value is not provided for this, NEST considers the query to be conditionless and does not serialize it as part of the query sent.
For example, given
var term = "term";
var to = DateTime.Now;
var from = to.AddDays(-7);
your current query serializes to
{
"query": {
"bool": {
"must": [
{
"query_string": {
"query": "term"
}
}
]
}
}
}
If the Field
is added
var result = client.Search<Ticket>(s => s
.Query(q => q
.Bool(b => b
.Must(ms => ms
.QueryString(qs => qs
.Query(term)
)
)
.Filter(f => f
.Bool(bb => bb
.Must(ms => ms
.DateRange(dr => dr
.Field(df => df.CreateDate)
.GreaterThanOrEquals(from)
.LessThanOrEquals(to)
)
)
)
)
)
)
);
this now serializes to
{
"query": {
"bool": {
"must": [
{
"query_string": {
"query": "term"
}
}
],
"filter": [
{
"bool": {
"must": [
{
"range": {
"createDate": {
"gte": "2018-07-17T12:20:02.8659934+10:00",
"lte": "2018-07-24T12:20:02.8659934+10:00"
}
}
}
]
}
}
]
}
}
}
Using operator overloading on queries, this can be written more succinctly
var result = client.Search<Ticket>(s => s
.Query(q => q
.QueryString(qs => qs
.Query(term)
) && +q
.DateRange(dr => dr
.Field(df => df.CreateDate)
.GreaterThanOrEquals(from)
.LessThanOrEquals(to)
)
)
);
which serializes to
{
"query": {
"bool": {
"must": [
{
"query_string": {
"query": "term"
}
}
],
"filter": [
{
"range": {
"createDate": {
"gte": "2018-07-17T12:21:50.2175114+10:00",
"lte": "2018-07-24T12:21:50.2175114+10:00"
}
}
}
]
}
}
}