CoreData - 获取另一个表中不存在的条目

时间:2014-03-28 14:17:44

标签: cocoa core-data nspredicate

给出两个表:

Data - Contains raw data, per value per day.
-----------
Value | Price | Date | DataType (string)

数据可能包含:

Units | Price | Date          | DataType
---------------------------------
10    | 0.99  | March 1, 2014 | "1A"
20    | 0.99  | March 1, 2014 | "1B"
4     | 0.99  | March 1, 2014 | "2"

可能有数十万条记录。

通常要查询Data我会使用谓词,例如(使用MagicalRecord):

NSArray * results = [Data MR_findAllWithPredicate: [NSPredicate predicateWithFormat: @"date > x AND date < y AND dataType IN ('1A', '1B')"]];

// Calculate sums per day.
// .... Loops through results, units * price summed per day.

但是由于行数很多,这种情况变得非常缓慢。

有一些事情我试图让这个更快。

  1. 通过NSExpression求和。不幸的是,由于需要使用multiple:by表达式,这不起作用。 (Fetch aggregate data from NSManagedObject using another expression as argument to sum: expression了解更多详情)。

  2. 现在我的想法是创建一个缓存表。我试图使用如下结构:

  3. CachedData
    -----------
    Sum | Date | CacheType (integer)
    

    我创建并测试了插入数据并且它似乎更快(我的一些计算从~7秒到约0.5秒)。但问题是通过核心数据创建此缓存表。

    如果我使用原始SQLite,我可以做类似的事情:

    INSERT INTO CachedData
      (CacheType, Sum, Date)
    
    SELECT
      0,
      (Value * Price),
      Date
    FROM
      Data
    WHERE
      DataType IN ('1A', '1B') AND
      NOT EXISTS(SELECT * FROM CachedData WHERE CacheType = 0 AND CachedData.Date = Data.Date);
    

    然后,任何时候数据都有新的插入(永远不会更新,只是插入),我可以快速运行这个查询,让它只更新我的新数据。

    另一方面,在coredata中,除了选择所有未缓存的数据,选择所有缓存的数据并做一些for循环之外,我似乎无法找到一个很好的方法来做到这一点。比较存在,然后插入。虽然这样可行,但它是SLOOOOOOOOW(相对于sqlite查询,可以在几秒钟内完成)。

    在考虑这个问题时,我认为一种简单的方法是在我的数据表中添加cached bool列。然后至少在我的枚举循环中,我可以对该列做一个谓词。我仍然有兴趣知道是否有办法通过coredata这样做而不添加额外的列。

    TL; DR

    有没有办法可以获取另一个表中不存在的一个表的所有记录?可能通过NSPredicate子查询?

1 个答案:

答案 0 :(得分:1)

首先,根据您的原始愿望,您是否将您的属性设置为索引?这有一些插入的开销,但会真正加快你想要的访问速度。

其次,为什么在插入数据时运行查询。您可以轻松地从MOC捕获DidSave通知,并为新插入的对象执行您想要的操作,其中包括添加到另一个存储中。或者,您可以使用NSFetchedResultsController并仅实现其委托...这将提供类似的结果,以便观察托管对象上下文中发生的事情......使用可能更熟悉的API。您不必使用带有TableView的FRC ......

相关问题