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

我的问题并不是真正的速度之一(尽管它肯定会出现在大型数据集的情况下),而是架构之一。我想知道如何代表我拥有的各种实体:

  • 包含文档列表(及其计数,微不足道)的叶类型节点(第一个示例中的叶节点
  • 一个包含叶子列表的刚刚上叶节点(第一个示例中的权重
  • 包含节点列表的 top-to-n-2 节点(第一个示例中的 size

我尝试从一个包含通用节点列表的通用抽象节点开始:但是,一旦我尝试从顶部注入文档,这种方法就会崩溃,因为每个节点都不知道自己的上下文并且没有不知道它应该在他之后创造什么。

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

在这样的结构中,节点不能插入到任意级别。(您的树是按属性分组的文档列表的表示。在任意级别插入意味着失去属性一致性,就好像您将单个单元格添加到表中,而不是代表具有完整属性集的文档的行。)所以,项目的插入和删除应该由树本身维护。

考虑这样的类结构(C#,因为我不擅长 VB 语法):

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 回答