嵌套树结构中的核心数据获取请求

Posted

技术标签:

【中文标题】嵌套树结构中的核心数据获取请求【英文标题】:Core Data fetch requests in nested tree structure 【发布时间】:2012-04-06 09:06:25 【问题描述】:

所以,我开始真正享受 Core Data,并开始将它集成到我正在开发的应用程序中。但是,我遇到了一个我看不到明显解决方案的问题,这让我觉得 Core Data 可能不是适合这项工作的工具。情况如下:我有一棵 Nodes 的树,每个树都可能有孩子,也可能没有孩子。可能有任意多个根Nodes。我已经使用一对多关系(从NodeNodes)和一对一逆向关系组合了数据模型。一切都很好。

现在,每个Node 也与Records 之间存在一对多关系,与Node 之间也存在一对多关系。我想要做的是找到所有Records,它们的特定布尔属性设置为true,并且在下面的某个地方是给定的Node。在我使用 Core Data 之前,这非常容易——我只是走在树上。然而,这很耗时,我希望 Core Data 能给我一种方法来发出一个获取请求,它可以快速获取我想要的所有Records。如果我知道要检查的最大深度,我可以很容易地看到如何做(半),但是如果我想一直向下怎么办?如果不是所有Nodes 都有孩子怎么办?

我应该像以前一样在树上走吗?

NSFetchRequest 甚至能够执行这样的任务吗?

【问题讨论】:

真的吗?没有人有任何相关经验可以分享? CoreData 非常适合这种类型的任务。但是,您可能应该更详细地说明您的数据模型布局,以及您实际遇到的问题。甚至可能是您想要获取的内容的示例。如果没有这些信息,我能做的最好的就是告诉您使用带有谓词的获取请求。你知道,你可以直接用“点”符号来跨越关系。 您需要什么样的细节?我有Node <-->> Node <-->> ... <-->> Node,每个节点都有Node <-->> Record。我想找到标记为paid 的所有Records,并且是给定节点的子节点(或其子节点之一,或其子节点等)。我知道如何使用谓词,问题是我可以'不要提前指定关卡的数量。即,我可以使用一个查看 child.child.records.paid == YES 或类似的谓词,但我只能得到正好向下两级的记录。 【参考方案1】:

这不是核心数据问题,而是图表问题。你必须做同样的搜索。但是,CoreData 可以让您在对象中出错。所以,你有几个选择,其中两个是

1) 走树。您应该能够使用与内存树中使用的完全相同的算法。 CoreData 应该只是在对象中出错。除非你有一棵非常深的树,否则应该没问题。

2) 对每条记录中的父关系进行编码。更新树时会进行大量更新,但获取速度会更快。

以下内容可以转换为 NSCompoundPredicate 并分配为 fetch 谓词...文档说它适用于 CoreData,但不适用于 sqllite - 试试吧。

NSPredicate *nodePredicate = [NSPredicate predicateWithFormat:@"field = %@", value];
// Use nodePredicate to find ones that match the ones you want to find
// Then use a block predicate to see if the parent is there.
NSArray *potential = [context executeFetchRequest:fetchRequest error:&error];
if (!error) 
    NSPredicate *parentPredicate = [NSPredicate predicateWithBlock:^BOOL(id obj, NSDictionary *bindings) 
        Node *node = obj;
        while (node) 
            if ([node.parent.nodeId isEqualToString:targetId) return YES;
            node = node.parent;
        
        return NO;
    ];
    NSArray *foundNodes = [potential filteredArrayUsingPredicate:parentPredicate];

【讨论】:

我不明白 2)。我已经在每条记录中编码父关系——作为子关系的逆。另外,这有什么帮助? 不管怎样,基本上你是说我的问题的答案是否定的,没有比走树更好的方法了吗? 您必须找到感兴趣的节点,然后从那里递归搜索树。如果您愿意在插入方面做一些额外的工作,那么您有多种选择。 1. 每个节点可以有另一个称为“父节点”的一对多关系,其中包含指向其每个父节点的链接。每当更新其层次结构时,都必须更新链接集,但您可以进行简单搜索,因为节点部分是在所有已付款设置为 YES 的节点中简单搜索“父母”列表。 ... 因此完全违背了使用 Core Data 的目的,因为我必须手动维护关系结构。太棒了,谢谢! 如果您使用任一步行算法,则无需维护父母列表。当您在 CoreData 中创建关联时,它会自动创建双向关联,而最好的部分 - 它会自动管理关系的完整性。

以上是关于嵌套树结构中的核心数据获取请求的主要内容,如果未能解决你的问题,请参考以下文章

POJ1195-数据结构嵌套(二维线段树)

使用 Python sqlparse 获取查询树/层次结构

JavaScript中嵌套对象结构中的递归树搜索

GraphQL 在嵌套图中获取子边的附加数据

Python字典的嵌套——用于决策树存储树结构

如何在 MySQL 中获取树结构中的数据? [复制]