我使用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 回答
我正在对你想要的东西做一些假设 . 请参阅我对原始问题的评论 . 但我认为这就是你所追求的 .
首先 - 您需要将
Page
类的ID更改为Id
而不是PageId
. 这是Raven将使用您的guid作为其文档ID的一部分 . 真的,你会更好地使用字符串ID,但这仍然有效 .然后,您可以执行以下操作:
这使用了RavenDB 2.0的新LoadDocument功能,它比您的场景更适合多 Map .
改变它所以它会是: