2015-01-21 39 views
4

我們正在Raven中存儲一組文檔。如何在RavenDB中創建具有多個分組的地圖/縮小索引

public class MyDocument 
{ 
    public string Id { get; set; } 
    public string DocumentType { get; set; } 
    public int ClientId { get; set; } 
    public string Status { get; set; } 
} 

我們希望顯示由客戶端Id和DocumentType都分組文件的報告,以便看起來像:

 
DocumentType ClientHasManyOfThese Count Action 
------------- -------------------- ----- --------------------- 
DocumentType1 Yes     10 LinkToListOfDocuments 
DocumentType1 No     5  LinkToListOfDocuments 
DocumentType2 Yes     12 LinkToListOfDocuments 
DocumentType2 No     15 LinkToListOfDocuments 

我創建了以下索引但它只返回正確的結果少量的文件。

public class MyDocumentCount 
{ 
    public string DocumentType { get; set; } 
    public int ClientId { get; set; } 
    public int Count { get; set; } 
    public bool MultipleDocumentsForClient { get; set; } 
} 

public class MyIndex : AbstractIndexCreationTask<MyDocument, MyDocumentCount> 
{ 
    public MyIndex() 
    { 
    Map = tasks => 
     from task in tasks 
     where task.Status = "Show In Report" 
     select new MyDocumentCount 
     { 
     DocumentType = task.DocumentType, 
     ClientId = task.ClientId, 
     MultipleDocumentsForClient = false, 
     Count = 1 
     }; 

    Reduce = results => 
     results.GroupBy(result => new 
     { 
     result.DocumentType, 
     result.ClientId 
     }).Select(conDocGrp => new MyDocumentCount 
     { 
     DocumentType = conDocGrp.Key.DocumentType, 
     Count = conDocGrp.Sum(result => result.Count), 
     MultipleDocumentsForClient = conDocGrp.Sum(result => result.Count) > 1, 
     ClientId = conDocGrp.Key.ClientId 
     }); 

    TransformResults = (database, results) => 
     results.GroupBy(result => new 
     { 
     result.DocumentType, 
     result.MultipleDocumentsForClient 
     }).Select(multDocGrp => new 
     { 
     multDocGrp.Key.DocumentType, 
     multDocGrp.Key.MultipleDocumentsForClient, 
     Count = multDocGrp.Sum(result => int.Parse(result.Count.ToString(CultureInfo.InvariantCulture))), 
     ClientId = 0 
     }); 
    } 
} 

我相信它在調用的時候有事情做與掠奪的結果次數限制:

var results = session.Query<MyDocumentCount, MyIndex>().ToList(); 

也許限制進行變換前應用於索引的結果?

有誰能告訴我我做錯了什麼,如果有辦法實現我想要的嗎?

我們目前正在運行RavenDB(Server Build 2380)。

謝謝。

+1

你爲什麼要將_int_轉換成_string_,然後再轉換成_int_? 'int.Parse(result.Count.ToString(CultureInfo.InvariantCulture))' – fgauna 2015-02-12 00:14:12

+0

我不完全明白你想要做什麼。你爲什麼在你的例子中爲DocumentType2的Count ='5'和ClientHasManyOfThese =否,當你的索引中的MultipleDocumentsForClient爲真時,當它超過1時。 – fgauna 2015-02-12 00:40:35

+0

對不起int.Parse(....)我真的不記得了這背後的推理。我從代碼庫中提取了這段代碼,我認爲在解決這個問題的背景中存在一些奇怪的事情。它看起來更簡單,因爲Count = multDocGrp.Sum(result => result.Count) – zonkflut 2015-02-12 05:15:08

回答

2

所以從我可以收集的問題的基本要點是,你正試圖聚合一個聚合。具體而言,您試圖通過ClientIdDocumentType進行分組,然後您試圖通過MultipleDocumentsForClient來彙總這些結果。您的索引適用於大多數情況,但是當Reduce產生的結果超過默認的RavenDB'頁面大小'限制時,您不會獲得所需的輸出。

我確認TransformResults只接收到RavenDB的頁面限制大小。你可以認爲TransformResults在客戶端執行,以確保你以後不會犯任何錯誤。也許這就是爲什麼它被棄用,我們應該使用變形金剛。

爲了解決你的問題,我認爲你在一個索引中做得太多了。變換器部分並不真正用於轉換查詢結果,而是用於再次聚合。 如果你不能在索引的Reduce部分做所有的聚合,那麼我建議你嘗試將索引拆分成兩個較小的索引。也許在這種情況下,當客戶擁有多個文檔時,可以使用一個索引,當客戶擁有單個文檔時可以使用一個索引。那麼你將不得不將這兩個結果加載到內存中,這似乎適合你的情況,因爲你已經在查詢中使用了.ToList

+0

嘿,謝謝你。 – zonkflut 2015-02-18 23:37:05

相關問題