首页 文章

RavenDB和分层文档

提问于
浏览
6

我使用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; }
}

因此,您可以看到这是关于渲染导航菜单 . 节点列表是分层的,可以在理论上无限深入(当然实际上只有2-4个子级别) . 起初我将Slug存储在节点中但是意识到,如果页面Slug发生变化会发生什么,当页面更改slug时更改所有节点我将不得不遍历所有菜单,爬下层次结构并找到要更改的所有Slug值它们听起来不是最佳解决方案 .

所以我认为应该可以构建一个索引,它将Page Slug与来自Node的其余数据结合在一个层次结构中 .

我一直在阅读有关Map Reduce,Multimap和recurse的内容,但我甚至不知道从哪里开始 .

我发现了这个http://ravendb.net/docs/2.0/client-api/querying/static-indexes/indexing-hierarchies

这是一个简单的例子,我试图让一些东西开始,我甚至无法让它工作,因为我真的不明白我链接到上面的页面上的例子 .

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?
                                      };
        }
    }

根据示例节点,节点不应该是集合,而是实际的NavigationNode对象 .

是否有可能在RavenDB中实现我想要的东西以及我在示例中做错了什么?

请随意询问任何令您困惑的事情 .

我为这种困惑道歉 . 我会试着解释一下 .

EDIT:

将PageId更改为字符串不会有问题 . 我正在使用Guids,因为我需要能够在插入之前生成主键ID:s . 无论如何,我想从索引查询的是一个导航链接的hiearachical树,其中包含Pages Slug . 所以我可以递归地循环出网站上的导航菜单 .

Matt Johnson的问题答案:

  • 我想要一个类的输出,你可以在下面看到

  • Page是一个单独的文档

  • 我只按菜单名称查询

public class NavigationIndexItem {public string MenuName {get;组; } public string Text {get;组; } public string Slug {get;组;公共字符串NodeType {get;组; public List ChildItems {get;组; }}

现在,当我看到上面的课程时,我想我可能会走错路 .

但无论如何,我会做一些小改动,谢谢Matt的回答 . 但是我仍然遇到和以前一样的问题 .

This row in your example: where node.PageId != null

node不是特定NavigationNode的实例,而是另一个集合,因此我无法检查其上的PageId属性 . 我只获得了一个LINQ扩展列表 .

2 回答

  • 3

    我正在对你想要的东西做一些假设 . 请参阅我对原始问题的评论 . 但我认为这就是你所追求的 .

    首先 - 您需要将 Page 类的ID更改为 Id 而不是 PageId . 这是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
                           };
        }
    }
    

    这使用了RavenDB 2.0的新LoadDocument功能,它比您的场景更适合多 Map .

  • 0

    改变它所以它会是:

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

相关问题