2011-02-24 72 views
7

我們使用烏鴉來驗證登錄,使人們可以進入我們的網站。查詢烏鴉與凡()只針對過濾前128個文件?

我們發現的是,如果你這樣做:

// Context is an IDocumentSession 
Context.Query<UserModels>() 
      .SingleOrDefault(u => u.Email.ToLower() == email.ToLower()); 

查詢只過濾在 烏鴉文件的前128個文檔。還有在我們的數據庫中幾千,所以,除非您的 電子郵件恰好是在返回的第一個128,你的運氣了。

Raven樣本代碼或我在網上遇到的任何 示例代碼都不會執行任何使用 Skip()和Take()遍歷該集合的循環。

  1. 這是烏鴉的期望行爲?
  2. 是,即使你使用了先進的Lucene查詢相同的行爲?即;高級查詢的行爲有什麼不同?
  3. 以下是合適的解決方案?看起來有點醜陋。 :P

我的解決辦法是遍歷集合中的所有文件,直到我遇到 一個非空的結果,那我會和回報。

public T SingleWithIndex(string indexName, Func<T, bool> where) 
{ 
    var pageIndex = 1; 
    const int pageSize = 1024; 
    RavenQueryStatistics stats; 

var queryResults = Context.Query<T>(indexName) 
    .Statistics(out stats) 
    .Customize(x => x.WaitForNonStaleResults()) 
    .Take(pageSize) 
    .Where(where).SingleOrDefault(); 

if (queryResults == null && stats.TotalResults > pageSize) 
{ 
    for (var i = 0; i < (stats.TotalResults/(pageIndex * pageSize)); i++) 
    { 
     queryResults = Context.Query<T>(indexName) 
      .Statistics(out stats) 
      .Customize(x => x.WaitForNonStaleResults()) 
      .Skip(pageIndex * pageSize) 
      .Take(pageSize) 
      .Where(where).SingleOrDefault(); 

     if (queryResults != null) break; 

     pageIndex++; 
    } 

} 

return queryResults; 

}

編輯:

使用下面的修復程序不通過查詢參數來我RavenDB實例。不知道爲什麼。

Context.Query<UserModels>() 
    .Where(u => u.Email == email) 
    .SingleOrDefault(); 

最後,我使用高級Lucene語法而不是linq查詢,並且事情按預期工作。

回答

4

RavenDB不理解SingleOrDefault,所以它執行一個沒有過濾器的查詢。然後您的條件在結果集上執行,但默認的Raven僅返回前128個文檔。 相反,你必須調用

Context.Query<UserModels>() 
     .Where(u => u.Email == email) 
     .SingleOrDefault(); 

所以濾波由RavenDB/Lucene的完成。

+0

我交叉發佈到谷歌組和Ayende提到他們還不支持SingleOrDefault()中的謂詞。我的問題證明,linq查詢不會傳遞查詢參數到我的服務器。 – 2011-02-24 16:32:34