1

这就是我的意思。

假设我们有大量数据,并且每个数据都有一个日期。

a: 2017/04/20
b: 2017/04/23
c: 2017/04/29
d: 2017/05/02
e: 2017/05/04

我们未来的目标是停止以这种方式存储数据,我们只想每月存储聚合数据。因此,我们希望在我们的示例中为 month 聚合数据 a&b&c 04,并在 month 中聚合数据 d&e 05

所以最后我们只需要2条数据。

在迁移中这样做是否合理,或者它不是真正的地方,或者甚至不可能?

本质上,[migration enumerateObjects:Data.className block:^(RLMObject *oldObject, RLMObject *newObject) {我们需要进入并计算出数据的月份,并保持运行总计。我们需要一些命令域来暂时不迁移该特定数据(因为在聚合完成之前我们不希望这样做)。然而,我们知道的唯一方法是当我们从 c 移动到 d,或从 04 月移动到 05 月时。那时,我们知道我们有我们的运行统计/聚合数据......我猜现在为时已晚现在迁移。

有谁知道这样的事情是否可能?我猜不是,它真的没有意义......但也许有人知道它肯定不起作用或有办法做到这一点。

4

1 回答 1

0

是的,您应该能够在迁移中做到这一点。

您可以多次遍历 Realm 文件中的所有对象,因此只需遍历所有对象,聚合每个月的值,然后再次遍历列表以应用新的价值观。您还可以删除迁移块内的对象,因此您还可以确保每月只保留一个对象:

id migrationBlock = ^(RLMMigration *migration, uint64_t oldSchemaVersion) {

    // Use a dictionary to store the aggregate values.
    // Dictionary keys must be unique, so they can be used to aggregate multiple values for a month.
   NSMutableDictionary *months = [[NSMutableSet alloc] init];

   //Loop through each object to extract and aggregate the data for each month
   [migration enumerateObjects:Data.className block:^(RLMObject *oldObject, RLMObject *newObject) {

        // Extract the month value from the date in this object
        NSDate *date = newObject["date"]; // Properties can be retrieved from RLMObject via KVC
        NSInteger month = date.month.intValue; // Extract the month from that date

        // Track if this was the first entry for this specific month
        BOOL firstTime = ([months.allKeys indexOfObject:@(month)] == NSNotFound);

        // Aggregate the value of month with the value stored in the dictionary
        NSInteger aggregateValue = months[@(month)].intValue;
        aggregateValue += date; // Add the month's information to the aggregate
        months[@(month)] = @(aggregateValue);

        // If this isn't the first object, we don't need it in Realm anymore, so delete it
        if (!firstTime) {
            [migration deleteObject:newObject];
        }
    }];

    // At this point, `months` will contain our aggregate values, and the Realm database
    // only has one object per month now.

    // Loop through all the objects again so we can add in the aggregate values
    [migration enumerateObjects:Data.className block:^(RLMObject *oldObject, RLMObject *newObject) {
        NSDate *date = newObject["date"];
        NSInteger month = date.month.intValue;

        // Copy in the aggregate value
        newObject["date"] = months[@(month)];
    }];
}

话虽如此,迁移是为数据库的实际架构发生变化而设计的。在这种情况下,看起来您的架构没有改变,而只是您要存储的数据的粒度发生了变化。

如果是这种情况,您可能更适合编写自己的辅助函数,该函数在应用程序启动时运行,检查您的数据是否已聚合,如果检测到未聚合则执行聚合。

于 2017-04-13T21:03:25.637 回答