1

Lucene.net から出てくるキーと値のドキュメントのリストがあり、ユーザーの入力に応じて、さまざまな値に応じてそれらをグループ化できるようにしたいと考えています。だから基本的に私は次のリストを持っています

Doc#1 - Weight:10;Size:20;ExpiresIn:90days
Doc#2 - Weight:10;Size:30;ExpiresIn:90days
Doc#3 - Weight:10;Size:20;ExpiresIn:30days
Doc#4 - Weight:10;Size:20;ExpiresIn:30days

そして、ユーザーに教えてもらいたい: これをサイズでグループ化し、次に重量でグループ化すると、次のようになります

Size: 20
 Weight: 10
  Count: 3
  Doc#1, Doc#3, Doc#4
Size: 30
 Weight: 10
  Count: 1
  Doc#2

しかし、彼は ExpiresIn でグループ化するように私に言うこともできます:

ExpiresIn: 90Days
 Count: 2
 Doc#1, Doc#2
ExpiresIn: 30Days
 Count: 2
 Doc#3, Doc#4

私の問題は実際には速度の問題ではなく (巨大なデータセットの場合には確かに存在しますが)、むしろアーキテクチャの問題です。私が持っているさまざまなエンティティをどのように表すことができるか知りたいです:

  • ドキュメントのリスト(およびそのカウント、自明)を含むリーフタイプのノード(最初の例のリーフノード
  • 葉のリストを含む葉のすぐ上にあるノード (最初の例では Weight )
  • ノードのリストを含む上位から n-2 のノード (最初の例では size )

一般的なノードのリストを含む共通の抽象ノードから開始しようとしましたが、各ノードは独自のコンテキストを認識せず、持っていないため、ドキュメントを一番上から挿入しようとすると、このアプローチは崩壊します。 t は彼の後に何を作成することになっているかについての手がかりを得た.

Public MustInherit Class Node(Of T)
    Implements IEnumerable(Of T)

    Private InnerValue As String
    Private InnerGrouping As String
    Protected InnerData As New List(Of T)

    MustOverride Sub AddGroupingElement(element As LuceneSearchResultsInfo)
End Class

Public Class LeafNode
    Inherits Node(Of LuceneSearchResultsInfo)

    Public Overrides Sub AddGroupingElement(element As LuceneSearchResultsInfo)
        InnerData.Add(element)
    End Sub
End Class

Public Class CommonNode
    Inherits Node(Of CommonNode)

    Public Overrides Sub AddGroupingElement(element As LuceneSearchResultsInfo)
        Dim InterestedNode = InnerData.FirstOrDefault(Function(n) n.Value = element.Field(Grouping))
        If (InterestedNode Is Nothing) Then
            InterestedNode = New CommonNode ' argh, i'm stuck, i don't know the rest of the context
        End If

    End Sub
End Class

ドキュメントへのフルパスをキーとして保存する簡単な辞書を保存することを考えていました。よりシンプルですが、専用の構造ほど快適に作業することはできません。だからどんなアイデアも歓迎します:)

4

1 に答える 1

1

このような構造では、ノードを任意のレベルに挿入することはできません。(ツリーは、属性でグループ化されたドキュメントのリストの表現です。任意のレベルで挿入すると、完全な属性が設定されたドキュメントを表す行ではなく、テーブルに単一のセルを追加するかのように、属性の一貫性が失われます。) 、アイテムの挿入と削除は、ツリー自体によって維持される必要があります。

そのようなクラス構造を考えてみてください(私はVB構文が苦手なので、C#):

class TableAsTree
{
    GroupingNode Root;  

    public void Insert(LuceneSearchResultsInfo sr)
    {
        /* Recursively insert */
        InsertToGroup(Root, sr); /* - root node would store all items */

    }

    public void InsertToGroup(GroupingNode node, LuceneSearchResultsInfo sr)
    {
        node.Documents.Add(sr.Document);
        //sample: Find "Weight" group with key = weight of current doc.
        var childGroup = ChildGroups.First(g => g.GroupKey == sr.Fields(g.GroupFieldName)); /*create if there is no group for the value*/
        InsertToGroup(childGroup, sr);
    }
}

class GroupingNode<TDocument>
{   
    string GroupKey;                    /* Group key value = 1 or 2 or 3 in (Size=1,2,3), no meaning for root */
    string GroupFieldName;              /* Group field name (Size), null for root */
    List<TDocument> Documents;          /* Documents at the level - you can add them for each level, or of the level before the last one */ 
    List<GroupingNode> ChildGroups;
}

これを使用すると、各グループ化レベルでドキュメントのリストを取得できます。

于 2012-10-09T08:06:05.343 に答える