簡體   English   中英

如何在 NEST C# 中編寫動態彈性搜索查詢

[英]how to write dynamic elastic search query in NEST C#

我有一個函數可以根據布爾標志在時間間隔內搜索文檔,如果在 if 語句中使用LessThanOrEqual和在 else 語句中使用LessThan ,NEST 查詢會有所不同。

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;
}

如何使用布爾標志“includeEnd”使這個 NEST 查詢動態化,這樣我就不需要使用 if 語句?

看看 LessThanOrEquals 和 LessThan 泛型擴展方法的作用。 基本上,它們擴展了 T 的 DateRangeQueryDescriptor(在這種情況下,T 是一本書),接受 DateMath 參數,並返回另一個 DateRangeQueryDescriptor。 因此,我們可以分解出一個函數,根據 includeEnd 標志,返回正確的函數以期望查詢描述符。

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();
}

為了進一步了解這個想法,您可以編寫自己的擴展方法:

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);
    }
}

然后你可以像這樣使用它:

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();

}

大多數 Nest fluent 接口擴展都以類似的方式對查詢描述符進行操作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM