我正在使用 Core Data 来存储由值和时间戳组成的简单实体。我正在寻找一个获取请求,它返回最新添加的值,以及所有值的运行平均值。这一切似乎都很简单,直到我尝试使用 NSPredicate 将结果过滤到特定时间段内。
我正在使用 NSExpression 的expressionForFunction:withArguments:
方法来确定平均值。通过设置启动标志-com.apple.CoreData.SQLDebug 1
,我可以清楚地看到只有最新的值符合我的日期谓词。相反,平均计算是作为子查询执行的,但没有考虑我的日期谓词:
SELECT (SELECT avg(t1.ZVALUE) FROM ZEVENT t1 WHERE t1.Z_ENT = ?), t0.ZVALUE FROM ZEVENT t0 WHERE ( t0.ZTIMESTAMP >= ? AND t0.Z_ENT = ?) ORDER BY t0.ZTIMESTAMP DESC
在仍然尊重我的 NSFetchRequest 谓词的同时确定平均值的最有效(和可扩展)的方法是什么?
作为参考,这是我的完整代码:
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"timestamp" ascending:NO];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Reading" inManagedObjectContext:moc];
[request setEntity:entity];
[request setSortDescriptors:@[sortDescriptor]];
[request setResultType:NSDictionaryResultType];
// Filter by date where necessary
NSPredicate *datePredicate = [NSPredicate predicateWithFormat:@"(timestamp >= %@)", toDate];
[request setPredicate:datePredicate];
NSExpression *valueExpression = [NSExpression expressionForKeyPath:valueKey];
NSExpressionDescription *valueDescription = [[NSExpressionDescription alloc] init];
[valueDescription setName:@"value"];
[valueDescription setExpression:valueExpression];
[valueDescription setExpressionResultType:NSDoubleAttributeType];
NSExpression *avgExpression = [NSExpression expressionForFunction:@"average:" arguments:[NSArray arrayWithObject:valueExpression]];
NSExpressionDescription *avgDescription = [[NSExpressionDescription alloc] init];
[avgDescription setName:@"averageReading"];
[avgDescription setExpression:avgExpression];
[avgDescription setExpressionResultType:NSDoubleAttributeType];
[request setPropertiesToFetch:@[avgDescription, valueDescription]];