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 のサブ レベルのみ)。最初はスラッグをノードに保存しましたが、ページのスラッグが変更され、ページがスラッグを変更したときにすべてのノードを変更するとどうなるか、すべてのメニューをループし、階層を下って、変更するすべてのスラッグ値を見つける必要があることに気付きました最適なソリューションとは思えません。

そのため、ページ スラッグとノードの残りのデータを階層構造で結合するインデックスを構築できるはずだと考えていました。

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 を文字列に変更しても問題ありません。挿入する前に主キー ID:s を生成できるようにする必要があるため、Guid を使用しています。とにかく、インデックスからクエリしたいのは、Pages Slug が含まれているナビゲーション リンクの階層ツリーです。そのため、Web サイトのナビゲーション メニューを再帰的にループアウトできます。

マット・ジョンソンの質問への回答:

  1. 以下に示すクラスの出力が必要です
  2. ページは別のドキュメントです
  3. メニュー名でのみクエリを実行します

    public class NavigationIndexItem { public string MenuName { get; 設定; } パブリック文字列テキスト { get; 設定; } パブリック文字列スラッグ { get; 設定; } パブリック文字列 NodeType { get; 設定; } public List ChildItems { get; 設定; } }

上記のクラスを見ると、少し間違った道を進んでいると思います。

とにかく、私はいくつかのマイナーな変更を行います。答えてくれたマットに感謝します。しかし、私はまだ以前と同じ問題に直面しています。

あなたの例のこの行: where node.PageId != null

node は特定の NavigationNode のインスタンスではなく、別のコレクションであるため、その PageId プロパティを確認できません。LINQ 拡張機能のリストのみを取得します。

4

2 に答える 2

3

私はあなたが望むものについていくつかの仮定をしています。元の質問に対する私のコメントを参照してください。しかし、これはあなたが求めているものだと思います。

Pageまず、クラスの ID をIdではなく に変更する必要がありますPageId。これは、Raven がドキュメント ID の一部として GUID を使用するためです。実際には、文字列 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機能を使用します。これは、シナリオのマルチマップよりもはるかに適しています。

于 2013-02-01T17:04:04.383 に答える
0

次のように変更します。

                            from node in Recurse(menu, x => x.Nodes.AsEnumerable())
于 2013-01-31T01:39:59.123 に答える