我在使用 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 与来自节点的其余数据以分层结构相结合。
我一直在阅读有关 Map Reduce、Multimap 和递归的信息,但我什至不知道从哪里开始。
我发现了这个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 中实现我想要的以及我在示例中做错了什么?
请随时提出任何您感到困惑的问题。
我为混乱道歉。我会试着解释一下。
编辑:
将 PageId 更改为字符串不会有问题。我正在使用 Guids,因为我需要能够在插入之前生成主键 ID:s。无论如何,我想从索引中查询的是包含 Pages Slug 的导航链接的层次结构树。所以我可以递归地循环出网站上的导航菜单。
回答马特约翰逊的问题:
- 我想要一个你可以在下面看到的类的输出
- 页面是一个单独的文档
我只会按菜单名称查询
公共类 NavigationIndexItem{ 公共字符串 MenuName { 获取;放; } 公共字符串文本 { 获取;放; } 公共字符串蛞蝓 { 得到;放; } 公共字符串节点类型 { 获取;放; } 公共列表 ChildItems { 获取;放; } }
现在,当我看到上面的课程时,我想我可能有点走错路了。
但无论如何,我会做一些小的改动,并感谢马特的回答。但是我仍然遇到和以前一样的问题。
您示例中的这一行: where node.PageId != null
node 不是特定 NavigationNode 的实例,而是另一个集合,因此我无法检查其上的 PageId 属性。我只得到一个 LINQ 扩展列表。