I have a function which does a search on documents in a time interval, based on a boolean flag, the NEST query would be different to use LessThanOrEqual in if statment and LessThan in else statement.
public IEnumerable<Book> GetBooks(DateTime startTime, DateTime endTime, string author, bool includeEnd)
{
var readRecords;
if (includeEnd){
readRecords = elastic.Search<Book>(s => s.Index(IndexName)
.Query(q => q.Term(book => book.Author, author) &&
q.DateRange(i => i.Field(book => book.Author)
.GreaterThanOrEquals(startTime)
.LessThanOrEquals(endTime)))).Documents.ToArray();
}
else{
readRecords = elastic.Search<Book>(s => s.Index(IndexName)
.Query(q => q.Term(book => book.Author, author) &&
q.DateRange(i => i.Field(book => book.Author)
.GreaterThanOrEquals(startTime)
.LessThan(endTime)))).Documents.ToArray();
}
return readRecords;
}
How can I make this NEST query dynamic using the boolean flag "includeEnd" so that I do not need to use the if statement?
Just take a look at what the LessThanOrEquals and LessThan generic extension methods do. Basically, they extend a DateRangeQueryDescriptor of T (in this case, T is a Book), accept a DateMath argument, and return another DateRangeQueryDescriptor. So, we can just break out a function that, depending on the includeEnd flag, returns the correct function to expect the query descriptor.
public IEnumerable<Book> GetBooks(DateTime startTime, DateTime endTime, string author, bool includeEnd)
{
var dateFilter = includeEnd ?
// you have to do a little casting for the lambdas to know what type we're returning
(Func<DateRangeQueryDescriptor<Book>, DateRangeQueryDescriptor<Book>>)
(q => q.LessThanOrEquals(endTime))
: q => q.LessThan(endTime);
return elastic.Search<Book>(s => s
.Index(IndexName)
.Query(q => q.Term(book => book.Author, author) &&
q.DateRange(i =>
{
i = i.Field(book => book.Author)
.GreaterThanOrEquals(startTime);
return dateFilter(i);
}
)))
.Documents
.ToArray();
}
To take this idea further, you could write your own extension method:
public static class DateQueryExtensions
{
public static DateRangeQueryDescriptor<T> LessThanWithOption<T>(this DateRangeQueryDescriptor<T> q, DateMath to, bool includeEnd)
where T : class
{
return includeEnd ? q.LessThanOrEquals(to) : q.LessThan(to);
}
}
Then you can use it like this:
public IEnumerable<Book> GetBooksUsingExtension(DateTime startTime, DateTime endTime, string author, bool includeEnd)
{
return elastic.Search<Book>(s => s
.Index(IndexName)
.Query(q => q.Term(book => book.Author, author) &&
q.DateRange(i => i.Field(book => book.Author)
.GreaterThanOrEquals(startTime)
.LessThanWithOption(endTime, includeEnd)
)))
.Documents
.ToArray();
}
Most of the Nest fluent interface extensions operate on query descriptors in a similar manner.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.