2012-03-19 36 views
3

方案:RavenDB索引覆蓋單個以及文檔中的對象列表

我目前在我們的網站內部創建了一個搜索功能。此功能用於返回符合所有給定條件的相冊。 IE瀏覽器。專輯標題,作曲家等。我對Raven中的全文搜索有所瞭解,我可能不得不嘗試使用它。

我希望儘管我可能會使用單個索引,而只是針對索引進行查詢。 (不幸的是,我現在還不知道爲什麼我應該/不應該這樣做,而不是全文索引,所以我願意提供建議:))

值得注意的事情...專輯是唯一的我們目前在Raven中收集的數據,因爲它是通過從備用系統導入的數據提供給烏鴉的。它可以被認爲是與專輯相關的所有事情的非規範化視圖。

下面是我們專輯的一個例子:

public class Album 
{ 
    public string Id { get; set; } 
    public string Title { get; set; } 
    public string Description { get; set; } 
    public List<string> Composers { get; set; } 
    public List<string> MusicCategories { get; set; } 
    public List<string> PerformingGroups { get; set; } 
    public List<string> Instruments { get; set; }    
} 

下面是我試圖創建索引。標題搜索有效,但當搜索集合中的項目時沒有返回結果。我只能想象它與我沒有對它們進行任何類型的映射/縮減和投影有關。但這只是我的一個猜測。

ravenSessionManager.DocumentStore.DatabaseCommands 
      .PutIndex("AlbumsBySearchCriteria", new IndexDefinitionBuilder<Album> 
      { 
       Map = albums => from a in albums 
           select 
            new 
            { 
             a.Title, 
             a.Composers, 
             a.MusicCategories, 
             a.Instruments 
            }, 
       Indexes = 
                 { 
                  {x => x.Title, FieldIndexing.Analyzed}, 
                  {x => x.Composers, FieldIndexing.Analyzed},FieldIndexing.Analyzed}, 
                  {x => x.MusicCategories, FieldIndexing.Analyzed},FieldIndexing.Analyzed}, 
                  {x => x.Instruments, FieldIndexing.Analyzed} 

                 } 
      }); 

最後下面是我的查詢的例子:

var query = (from a in _documentSession.Query<Album>("AlbumsBySearchCriteria") 
         select a); 

      if(!string.IsNullOrEmpty(criteria.Title)) 
       query = query.Where(a => a.Title.StartsWith(criteria.Title)); 
      if (!string.IsNullOrEmpty(criteria.Composer)) 
       query = query.Where(a => a.Composers.Any(c => c.StartsWith(criteria.Composer))); 
return query; 

預先感謝任何幫助/指導,你可以提供。任何幫助或建議將非常感激。

+0

我完全是RavenDB和Lucene的新手,但我會預料到這個工作。爲了學習一些關於使用Lucene.NET的知識,我深入研究了RavenDB源代碼,並且我認爲RavenDB會爲您的消費者列表中的每個元素提供一個消費者字段給Lucene。 – 2012-03-19 17:33:05

+0

是啊,我也是:)。奇怪的是,我和這裏的另一位開發人員都會發誓,我們在幾天前就開始工作,因爲我們已經對它進行了宗教測試。現在由於某種原因,它不起作用。根據我們的源代碼控制,沒有做出任何改變:)。我目前正在嘗試Daniel的建議。它正在工作,如果我只爲每個搜索輸入一個標準,但不符合多個標準。我會確保更新,如果我得到它的工作。感謝您查看此和評論。我很感激。 – TheWeekendDeveloper 2012-03-19 18:08:00

回答

1

好吧,我已經想出了我面臨的問題,我想我會分享一些背景知識,並讓其他人看到我所犯的錯誤。首先我要感謝丹尼爾的回答。他的解決方案確實會工作得很好。還值得一提的是,我的原始解決方案也能起作用,只要你不犯我犯的那些愚蠢的錯誤:)。

錯誤#1:我的解決方案最初出現失敗,原因是我沒有意識到新的ETL文檔以及舊的不正確的索引。不幸的是,我想「在野草叢中」注意到。

錯誤#2:丹尼爾斯的例子就是我需要如此不正是我不得不做一些調整,同時調整我忘了把「作爲<‘動態’>」到我的查詢像丹尼爾的例子有。

如果要照你的查詢作爲該文檔保存爲索引不會返回同一類型的原始CLR型的結果,那麼就以添加「作爲<重要的「動態'>()「或」AsProjection <'SomeType'>()「。因爲在查詢時Raven會將文檔的clr類型轉換爲您在索引中指定的clr類型。在我的情況下,究竟發生了什麼。我想按照我的結果來處理類型相冊,但從查詢返回的文檔正在從「相冊」類型更改爲「ReduceResult」,正如人們所期望的那樣。我沒想到的是,它會在文檔中標記它已更改的更改,並且如果調用SaveChanges(),它現在會將我的文檔保存爲新類型。這導致我錯誤的數字3。

錯誤#3:一切,我所做的就是在「工作單位」的格局,我忘記了我的http請求的最後,我叫ravenSession.SaveChanges()。這是什麼封住了我的命運:(因爲我在錯誤2中提到的查詢期間改變了我的類型,所以現在我發現自己在同一個集合中有不同的clr類型的文檔

最終結果是每次我在我的索引上執行了一個搜索,它返回了多個具有不同clr類型的文檔,我將得到一個無效的轉換異常。爲了讓事情變得更糟,我抓住了所有異常,以便我可以適當地處理它們,並將特定結果返回給因此我的SaveChanges()總是被觸發,因此使用不同的clr類型將文檔添加回到我的相冊集合中,而沮喪的圈子仍在繼續。 ...

  1. 如果你想使用/行爲的專輯上的代碼中,請確保您的索引後,會迴文件作爲相冊,或者你的索引帶回什麼都減少你想要的結果塔伊,但請確保您在查詢中添加了As <'dynamic'>()或AsProjection <'Sometype'>()方法。這應該防止更改文檔clr類型的結果。

  2. 確保你沒有任何session.SaveChanges()被調用,你忘記了。

  3. 總是檢查您的索引,以確保它們是最新的。

總之,不要犯同樣的愚蠢錯誤,我做了。顯然我的無知沒有界限:)

再次感謝兩位丹尼爾斯的迴應。我很感激幫助。