2013-10-28 72 views
4

我想用NEST附加多個布爾過濾器,但是我不能(在一般情況下)在單個語句中這樣做,因爲我想構建一組依賴於過濾器的篩選器在不同的條件下。將多個布爾過濾器追加到NEST查詢

事情是這樣的僞代碼:

// Append a filter 
searchDescriptor.Filter(f => f.Bool(b => b.Must(m => m.Term(i => i.SomeProperty, "SomeValue")))); 

if (UserId.HasValue) 
{ 
    // Optionally append another filter (AND condition with the first filter) 
    searchDescriptor.Filter(f => f.Bool(b => b.Must(m => m.Term(i => i.AnotherProperty, "MyOtherValue")))); 
} 

var result = Client.Search(searchDescriptor); 

現在看來,當第二個可選的過濾器被添加,它本質上替換第一個過濾器。

我敢肯定,我想的東西語法,但我無法弄清楚和NEST文檔是有點薄在過濾器DSL。 :)

回答

12

上編寫查詢的部分幾乎適用於過濾器,以及: http://nest.azurewebsites.net/nest/writing-queries.html

你結束瞭解決的辦法是小於因爲你在and過濾器中包裝bool過濾器,它具有非常不同的高速緩存機制(並且過濾器不使用高速緩存的位集,因此在大多數情況下執行比常規的bool過濾器更差)。

強烈建議你閱讀http://www.elasticsearch.org/blog/all-about-elasticsearch-filter-bitsets/,因爲它解釋得很好什麼VS布爾過濾器和/或/沒有過濾器的區別是。

實際上,你可以重寫這個像這樣:

Client.Search(s=>s 
    .Filter(f=> { 
     BaseFilter ff = f.Term(i => i.MyProperty, "SomeValue"); 
     if (UserId.HasValue) 
      ff &= f.Term(i => i.AnotherProperty, "AnotherValue"); 
     return ff; 
    }) 
); 

如果第二項是使用用戶ID,您可以利用NEST的conditionless queries

Client.Search(s=>s 
    .Filter(f=> 
     f.Term(i => i.MyProperty, "SomeValue") 
     && f.Term(i => i.AnotherProperty, UserId) 
    ) 
); 

如果UserId爲null,則術語查詢韓元的搜索「T被genererated作爲查詢的一部分,窩在這種情況下,甚至不會換行剩餘的獨詞在布爾過濾器,但只是將其作爲一個普通的術語濾鏡代替。

1

啊,這樣的事情似乎工作:

 var filters = new List<BaseFilter>(); 

     // Required filter 
     filters.Add(new FilterDescriptor<MyType>().Bool(b => b.Must(m => m.Term(i => i.MyProperty, "SomeValue")))); 

     if (UserId.HasValue) 
     { 
      filters.Add(new FilterDescriptor<MyType>().Bool(b => b.Must(m => m.Term(i => i.AnotherProperty, "AnotherValue")))); 
     } 

     // Filter with AND operator 
     searchDescriptor.Filter(f => f.And(filters.ToArray())); 

     var result = Client.Search(searchDescriptor); 
相關問題