2017-04-11 114 views
1

这是我的意思。在Realm迁移过程中,如何进行多对一迁移?

比方说,我们有大量的数据,他们每个人都有一个日期。

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

我们未来的目标是停止以这种方式存储数据,我们只想存储每月的汇总数据。因此,我们想要在月 c中合计数据& b ,并在月份05中合计数据d &e。

所以最后我们只想要2个数据。

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

本质上在[migration enumerateObjects:Data.className block:^(RLMObject *oldObject, RLMObject *newObject) {我们需要进入并计算出数据的月份,并保持总计。我们需要一些让领域在此时不迁移该特定数据的命令(因为我们不想在聚合完成之前)。然而,我们唯一知道的方式是当我们从c移到d时,或者从04到05月。那时,我们知道我们有我们的运行/汇总数据......我猜测现在已经太迟了现在正在迁移。

有谁知道这样的事情是否可能?我不会猜测,这不是真的有意义......但也许有人在那里知道它绝对无效或有办法做到这一点。

回答

0

是的,你应该可以在迁移中完成它。

您可以遍历Realm文件中的所有对象多次,因此它应该只是遍历所有对象,汇总每个月的值,然后遍历列表a第二次应用新值。您也可以删除迁移块内的对象,所以你也可以确保只有一个对象,每月仍然是:

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)]; 
    }]; 
} 

话虽这么说,移民是专为当你的数据库更改的实际架构。在这种情况下,它看起来像你的模式没有改变,但只是你想要存储的数据的粒度。

如果是这种情况,那么编写自己的帮助程序函数可能会更合适,该函数在应用程序的开始时运行,检查您的数据是否已经聚合,并在检测到它时执行聚合不是。