如何对 CoreData 中的许多关系执行复合查询

Posted

技术标签:

【中文标题】如何对 CoreData 中的许多关系执行复合查询【英文标题】:How to perform a compound query against to many relationships in CoreData 【发布时间】:2016-08-16 01:38:28 【问题描述】:

我正在寻求一些帮助来理解 NSPredicates 以及如何查询 CoreData。这是我所拥有的:

我有两个实体:1. Capture 表示“捕获”某些数据,它与 2. 身份标签有一对多关系。

我希望从一组特定的“捕获”中获得一组“身份”标签。即,我想知道名称为“X”的所有唯一身份,以获取也标记为 Int 'y' 的 id 的捕获。

我很快就会这样建模:

let captures: [Capture]
let identities = captures.flatmap( $0.identities ).filter( $0.id == "y" )
let uniqueIdentitiesOfParticularType: Set<Identity> = Set(identities.flatMap( $0.name )

有什么帮助吗?

【问题讨论】:

【参考方案1】:

首先,一定要从Predicate Programming Guide 开始,它会详细介绍更多内容。请特别参阅“将谓词与核心数据一起使用”。

如果您想对故障小心一点,您的解决方案可能是这样的:

let request = NSFetchRequest(entityName: "Capture")
let id = "y"
request.predicate = NSPredicate(format: "id == %@", id)
let identities = try context.executeFetchRequest(request) as NSArray
let names = identities.valueForKeyPath("@distinctUnionOfObjects.name")

请注意,ios 10 为此向 Swift 添加了更好的桥梁(您可能不需要as NSArray),但我还没有真正探索它们。

有关@distinctUnionOfObjects 及其朋友的更多信息,请参阅Collection Operators。

【讨论】:

谢谢罗伯!这让我走上了正轨。我想我认为可能有更好的方法来告诉 CoreData 一次性获取这些对象,因此我试图弄清楚如何让 NSPredicates 完成所有工作。 请记住,Core Data 不是数据库。它的目的不是任意记录查询。它是一个对象持久化引擎。它的目的是保持一致的对象图。 “获取”只是一个实现细节,因为数据集可能并不都适合内存。 Core Data 的主要功能是帮助您导航复杂的关系系统,而不是“查询行”。如果你有很多独立的记录,没有很多固定的关系,我经常会发现数据库是更好的工具。 我很感激...对于我正在从事的这个小项目,我有一个本地存储在 JSON 中的数据集。 CoreData 只是提供了一种很好的方法来将这些数据序列化为适当的对象,维护它们之间的关系,并与它们进行交互。我认为在探索这个解决方案时,我可能试图过度设计,认为有更好的方法,然后查看 fetch 返回的所有对象。

以上是关于如何对 CoreData 中的许多关系执行复合查询的主要内容,如果未能解决你的问题,请参考以下文章

如何以某种通用方式删除有序对多 CoreData 关系中的对象?

MongoDB通过许多参数过滤(复合索引与否)

具有日期范围的 CoreData 复合提取的意外结果

更新 laravel 关系中的许多记录

如何管理 Core Data 中的一对多关系?

CoreData - 在实体上有许多关系时的性能