2015-01-21 35 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

相关问题