2012-03-27 16 views
5

考虑以下类:最简单的方式来拉平文档视图中RavenDB

public class Lookup 
{ 
    public string Code { get; set; } 
    public string Name { get; set; } 
} 

public class DocA 
{ 
    public string Id { get; set; } 
    public string Name { get; set; } 
    public Lookup Currency { get; set; } 
} 

public class ViewA // Simply a flattened version of the doc 
{ 
    public string Id { get; set; } 
    public string Name { get; set; } 
    public string CurrencyName { get; set; } // View just gets the name of the currency 
} 

我可以创建一个允许客户端查询视图如下指标:

public class A_View : AbstractIndexCreationTask<DocA, ViewA> 
{ 
    public A_View() 
    { 
     Map = docs => from doc in docs 
         select new ViewA 
         { 
          Id = doc.Id, 
          Name = doc.Name, 
          CurrencyName = doc.Currency.Name 
         }; 

     Reduce = results => from result in results 
         group on new ViewA 
         { 
          Id = result.Id, 
          Name = result.Name, 
          CurrencyName = result.CurrencyName 
         } into g 
         select new ViewA 
         { 
          Id = g.Key.Id, 
          Name = g.Key.Name, 
          CurrencyName = g.Key.CurrencyName 
         }; 
    } 
} 

这肯定工程并将数据转换为客户端应用程序所需的结构,从而生成所需的视图结果。然而,这是不可行的冗长的,将是一个维护噩梦,并可能是相当低效的所有冗余对象的建设。

是否有一种更简单的方式创建一个具有所需结构(ViewA)的索引给定文档集合(DocA)?

更多信息请 问题似乎是为了有指数保持在转化结构(ViewA)的数据,我们做了减少。看来,一个减少必须同时具有GROUP ON以及选择以工​​作为预期的那么以下是无效的:

无效REDUCE条款1:

 Reduce = results => from result in results 
         group on new ViewA 
         { 
          Id = result.Id, 
          Name = result.Name, 
          CurrencyName = result.CurrencyName 
         } into g 
         select g.Key; 

这将产生:系统。 InvalidOperationException:变量初始值设定项选择必须有一个带有对象的lambda表达式创建表达式

显然,我们需要“选择新的”。

INVALID REDUCE第2项目:

 Reduce = results => from result in results 
         select new ViewA 
         { 
          Id = result.Id, 
          Name = result.Name, 
          CurrencyName = result.CurrencyName 
         }; 

这prduces:System.InvalidCastException:无法投类型 'ICSharpCode.NRefactory.Ast.IdentifierExpression' 的目的为类型“ICSharpCode.NRefactory.Ast.InvocationExpression ”。显然,我们还需要有'新组'。

感谢您提供任何帮助。

(注:从构造函数调用删除类型(ViewA)对上述无效)

与正确的做法UPDATE

正如在回答下面所提到的,在这里丹尼尔的博客概述就是在这个例子中做到这一点的正确方法:

public class A_View : AbstractIndexCreationTask<DocA, ViewA> 
{ 
    public A_View() 
    { 
     Map = docs => from doc in docs 
         select new ViewA 
         { 
          Id = doc.Id, 
          Name = doc.Name, 
          CurrencyName = doc.Currency.Name 
         }; 

     // Top-level properties on ViewA that match those on DocA 
     // do not need to be stored in the index. 
     Store(x => x.CurrencyName, FieldStorage.Yes); 
    } 
} 
+0

谢谢@Phill。我不知道在这里发生的其他答案发生了什么...... – 2012-11-01 22:49:42

回答

4

一个解决方案,在地图只需压平,并配置指标只存储不存在DOCA性能。

public class A_View : AbstractIndexCreationTask<DocA, ViewA> 
{ 
    public A_View() 
    { 
     Map = docs => from doc in docs 
         select new ViewA 
         { 
          Id = doc.Id, 
          Name = doc.Name, 
          CurrencyName = doc.Currency.Name 
         }; 

     // Top-level properties on ViewA that match those on DocA 
     // do not need to be stored in the index. 
     Store(x => x.CurrencyName, FieldStorage.Yes); 
    } 
} 
+0

只是我注意到了一段时间我正在寻找的东西;如果您想使用索引来查询,然后获取您要查询的原始实体,可以这样做: 'DocumentSession.Query ()。其中​​(x => x.CurrencyName == “欧元”)。由于()。First();' [Found here](http://ayende.com/blog/152833/orders-search-in-ravendb) – 2013-07-11 12:49:16

相关问题