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

时间:2012-04-06 09:06:25

标签: iphone ios core-data tree nsfetchrequest

所以,我只是真正享受Core Data,并开始将其集成到我正在开发的应用程序中。但是,我遇到了一个问题,我没有看到任何明显的解决方案,这让我觉得Core Data不是正确的工具。情况就是这样:我有一棵Node的树,每棵都有或没有孩子。可能有任意多个根Node。我已经使用to-many关系(从NodeNode s)将数据模型与一对一关系放在一起。一切都很好。

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

我应该像往常一样走树吗?

NSFetchRequest是否能够执行此类任务?

1 个答案:

答案 0 :(得分:2)

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

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

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

以下内容可以转换为NSCompoundPredicate并指定为fetch谓词... Docs说它适用于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];
}