这就是我的意思。
假设我们有大量数据,每条数据都有一个日期。
a: 2017/04/20
b: 2017/04/23
c: 2017/04/29
d: 2017/05/02
e: 2017/05/04
我们 future 的目标是停止以这种方式存储数据,我们只想按月存储汇总数据。因此,我们希望在示例中聚合 04
月的数据 a&b&c,并在 05
月聚合数据 d&e。
所以最后我们只想要2条数据。
在迁移中这样做是否合理,或者它不是真正的地方,或者甚至不可能?
本质上,在 [migration enumerateObjects:Data.className block:^(RLMObject *oldObject, RLMObject *newObject) {
中,我们需要进去找出数据的月份,并保留一个运行总计。我们需要一些命令让 Realm 此时不迁移该特定数据(因为我们不想在聚合完成之前迁移)。然而,我们知道的唯一方法是当我们从 c 移动到 d,或从 04 月到 05 月。那时,我们知道我们有我们的运行计数/聚合数据......我猜现在为时已晚现在迁移。
有谁知道这样的事情是否可能?我猜不是,它真的没有意义......但也许外面有人知道它肯定行不通或有办法做到这一点。
最佳答案
是的,您应该能够在迁移中完成。
您可以多次遍历 Realm 文件中的所有对象,因此应该只是遍历所有对象、汇总每个月的值,然后迭代第二次通过列表以应用新值。您还可以删除迁移 block 内的对象,这样您也可以确保每个月只保留一个对象:
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)];
}];
}
也就是说,迁移是为数据库的实际模式发生变化而设计的。在这种情况下,您的模式似乎没有发生变化,只是您要存储的数据的粒度发生了变化。
如果是这种情况,您可能更适合编写自己的辅助函数,该函数在您的应用启动时运行,检查您的数据是否已聚合,并在检测到未聚合时执行聚合't.
关于objective-c - 在 Realm 迁移期间,如何进行多对一迁移?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43355159/