CoreData按属性的唯一对象

时间:2010-02-12 16:36:09

标签: cocoa core-data

我有一个名为Message的对象图。消息可以包含子节点,因此图形是树。 图上的每个对象都包含一个属性值;这是一种UUID(全局唯一),因此存储不能包含具有相同UUID的多个消息(此uuid是从消息数据中获取的字符串,因此我无法使用nsmanagedobject的objectID替换它)。 当我需要验证对象插入到商店时,会发生问题。 如何检查商店中是否已存在具有相同UUID的消息?我正在考虑对validateForInsert:事件的获取请求,但是当有大量对象要插入时(在我的情况下大约为30k),它似乎太慢/太复杂。 任何人都有最好的解决方案吗?

4 个答案:

答案 0 :(得分:4)

这是CoreData的一个已知限制(我自己已经提交了一个功能请求)。您还应该转到http://bugreport.apple.com并让他们知道您想要此功能。 (最初的错误ID是rdar:// 3711805)

我过去解决这个问题的方法是使用便捷方法来访问和创建我的NSManagedObjects。然后,这种便捷方法在静态NSMutableDictionary中查找,以查看是否已经创建了具有相同唯一属性的另一个对象(唯一属性是键,而managedObjectID是值)。如果找到一个,则只返回该对象。如果没有,那么它将创建一个并将该对象的ID缓存到静态字典中以供将来使用。当应用程序首次启动时,我必须使用预先存在的对象的属性/标识符预先填充此字典。

这是一种痛苦,我知道。 :(提交增强请求。

答案 1 :(得分:0)

好的第二个索引结果更好,所以我尝试对问题和解决方案进行总结。如果有人有更好的主意我会很高兴谈论它:) 我从网络中获取了大约30,000条消息,我需要以树的形式将所有消息保存到Core Data Store中。 每条消息都包含一个唯一的标识字符串,并且只能在具有相同ID的数据库中保存一条消息。 CoreData目前不支持属性的唯一性,我不能使用objectID属性来确保这种事情。 第一个解决方案是伪代码: - 执行查询以查看存储中是否存在uuid字符串 - 如果它不存在,我可以使用该uuid创建一个新的NSManagedObject并将其存入存储,否则我将忽略它(它已经在db上) - 执行另一个查询以查找此新消息的直接父级,如果找到,我将链接两个消息,如果不是,则它是根消息

这个解决方案存在很大问题。使用30k消息我需要30k查询来检查coredata上是否存在新消息,另外30k检查父节点(加上,我认为,另外30k插入新对象)。超过60k +查询需要花费大量时间(此处为一分钟或更长时间)。

我的第二个解决方案是创建第二个辅助NSMutableDictionary,其中我将消息uuid保存为键,NSManagedObjectID的URI表示(我唯一可以保存到NSData)作为字典条目的值。 伪代码的结果是: - 使用objectForKey:uuid到我的辅助字典,看看该信息是否存在于coredata中 - 如果是,我会忽略它。如果不是我会把它放进商店 - 使用objectForKey:parentuuid到我的辅助字典,以查看消息的父节点是否存在于coredata上。如果是,我将使用NSPersistentCoordinator的managedObjectIDForURIRepresentation:获取NSManagedObject(消息的父节点)并链接父节点和子节点

使用此解决方案,整个过程大约需要5秒钟(结果字典大约为2mb)。

答案 2 :(得分:0)

我已经使用这两种技术上传了一个示例项目。 使用coredata + indexed属性需要大约4分钟才能保存(出了什么问题?!!) 使用辅助索引需要大约3秒钟才能保存。 随意评论它。 这很奇怪,尤其是在我阅读之后: http://cocoawithlove.com/2008/03/testing-core-data-with-very-big.html 这是我的代码项目: http://dl.dropbox.com/u/103260/CoreDataTreeTest2.zip

答案 3 :(得分:0)

一个临时解决方案(感谢来自Cocoa-dev的Roland),如果有人想使用CoreData,就是保存每个X插入的上下文。在我的情况下使用([ctx save:])每个500/1000插入下拉时间从几分钟到几秒(实现此解决方案的另一个项目可在此处获取:http://dl.dropbox.com/u/103260/CoreDataTreeTest3.zip

这些是我的基准,有30.000个对象:

  • CoreData ,不保存每个X. 插入:约5-6分钟
  • CoreData 保存每500次插入:约30秒
  • CoreData 辅助索引字典:约2秒

然而,这似乎很奇怪。

根据: http://cocoawithlove.com/2008/03/testing-core-data-with-very-big.html

它应该比这快,并且30k对象是CoreData的少数对象。我想尝试填补bugreporter的一个错误,听听Apple Engineers的说法。