我有一个来自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
我的问题实际上不是速度问题(虽然它肯定会出现在大型数据集的情况下),而是一种架构。我想知道我如何代表我拥有的各种实体:
我尝试从一个包含通用节点列表的公共抽象节点开始:但是,一旦我尝试从顶部注入文档,这种方法就会崩溃,因为每个节点都不知道自己的上下文并且没有了解它应该在他之后创造的东西。
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
我在考虑存储一个简单的字典,其中包含存储为密钥的文档的完整路径。它更简单,但不像真正的专用结构那样令人愉快。所以欢迎任何想法:)
答案 0 :(得分: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;
}
使用它,您将能够获取每个分组级别的文档列表。