Recursion RavenDB和分层文档

Recursion RavenDB和分层文档,recursion,ravendb,hierarchical-data,Recursion,Ravendb,Hierarchical Data,我在使用RavenDB解决此问题时遇到困难。我有这些课程。 我从中排除了很多属性,以保持示例的简单性 public class Menu { public string Name { get; set; } public List<NavigationNode> Nodes { get; set; } } public class NavigationNode { public string Text { get; set; } public Gui

我在使用RavenDB解决此问题时遇到困难。我有这些课程。 我从中排除了很多属性,以保持示例的简单性

public class Menu
{
    public string Name { get; set; }
    public List<NavigationNode> Nodes { get; set; }
}

public class NavigationNode
{
    public string Text { get; set; }
    public Guid? PageId { get; set; }
    public string NodeType { get; set; }
    public List<NavigationNode> Nodes { get; set; }
}

public class Page
{
    public Guid PageId { get; set; }
    public string Slug { get; set; }
}
公共类菜单
{
公共字符串名称{get;set;}
公共列表节点{get;set;}
}
公共类导航节点
{
公共字符串文本{get;set;}
公共Guid?PageId{get;set;}
公共字符串节点类型{get;set;}
公共列表节点{get;set;}
}
公共类页面
{
公共Guid页面ID{get;set;}
公共字符串Slug{get;set;}
}
如您所见,这是关于呈现导航菜单的。节点列表是分层的,理论上可以无限深入(当然,实际上只有2-4个子级别)。起初,我将Slug存储在节点中,但意识到,如果页面Slug发生变化,会发生什么情况?当页面改变Slug时,更改所有节点我必须循环所有菜单,沿着层次结构向下爬,找到所有这些Slug值来更改它们,这听起来不是最佳解决方案

因此,我认为应该可以构建一个索引,以层次结构将页面Slug与节点中的其余数据结合起来

我一直在读关于Map-Reduce、Multimap和recurse的书,但我甚至不知道从哪里开始

我找到了这个

这是一个简单的例子,我只是想开始做一些事情,但我甚至不能让它工作,因为我真的不理解我上面链接的页面上的例子

  public class NavigationIndex : AbstractIndexCreationTask<Menu>
   {
        public NavigationIndex()
        {
            Map = menus => from menu in menus
                           from node in Recurse(menu, x => x.Nodes)
                           select new
                                      {
                                          WhatIsThis = node // <- Why is this a collection?
                                      };
        }
    }
公共类导航索引:AbstractIndexCreationTask
{
公共导航索引()
{
映射=菜单=>从菜单中的菜单
从递归中的节点(菜单,x=>x.Nodes)
选择新的
{

WhatIsThis=node/将其更改为:

                            from node in Recurse(menu, x => x.Nodes.AsEnumerable())

我在对你想要的东西做一些假设。看我对最初问题的评论。但我认为这就是你想要的

首先-您需要将
页面
类的id更改为
id
,而不是
页面id
。这是因为Raven将使用您的guid作为其文档id的一部分。实际上,您最好使用字符串id,但这仍然有效

然后您可以执行以下操作:

public class NavigationIndex : AbstractIndexCreationTask<Menu>
{
    public NavigationIndex()
    {
        Map = menus => from menu in menus
                       from node in Recurse(menu, x => x.Nodes)
                       where node.PageId != null
                       let page = LoadDocument<Page>("pages/" + node.PageId)
                       select new
                       {
                           menu.Name,
                           node.Text,
                           node.PageId,
                           page.Slug
                       };
    }
}
公共类导航索引:AbstractIndexCreationTask
{
公共导航索引()
{
映射=菜单=>从菜单中的菜单
从递归中的节点(菜单,x=>x.Nodes)
其中node.PageId!=null
让page=LoadDocument(“pages/”+node.PageId)
选择新的
{
菜单,名字,
node.Text,
node.PageId,
第页,鼻涕虫
};
}
}

这使用了RavenDB 2.0的新功能,它比多地图更适合您的场景。

但是节点仍然是一个集合。因此结果是一样的。我认为RavenDB页面上的教程中可能有输入错误。它显示了一个带有帖子和分层注释的示例。我有菜单和分层导航节点。Questions:1)你想让输出看起来像什么?你的问题还不清楚。2)
Page
是一个单独的文档吗?如果是的话,你设置使用Guid标识符了吗?可以这样做,但是Raven使用字符串标识符会更好。3)你想查询什么?我添加了一些说明。类都是混乱的stackoverflowswysiwyg编辑器只是不将其格式化为代码:/尝试了几次谢谢Matt我解决了它并得到了预期的结果。一件有趣的事。我注意到我有一个对RavenClient 1.x的引用。在这种情况下,您得到的不是实际的实例,而是一个集合。谈论这一行:where node.PageId!=null。在RavenClient 1.x node中是一款收藏在2.x我得到的实物。谢谢你的帮助,非常感谢!