我已经在这里和所有地方阅读了我在这个主题上发现的所有内容,但仍然无法弄清楚如何做我需要的。
我在核心数据db中有一个简单的事件对象,其属性如title, status, startDate, endDate, dayDate
,其中status
是整数,有3个可能的值,dayDate
是没有时间的日期(或午夜日期)
我需要收集有关数据库中事件的一些统计信息,按天分组并具有不同状态的事件计数。在示例中,我需要像伪字典这样的结果:
`
[
@{
@"dayDate" : ...someDate..
@"eventsCountTotal" : 8,
@"eventsWithStatus1" : 4,
@"eventsWithStatus2" : 3,
@"eventsWithStatus3" : 1
}
@{
...stats for another day
}
]
`
使用CoreData完全可以使用一个查询吗?我目前正在做这个以获得一些统计数据,但这不是我想要的:
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"SWEvent"];
request.resultType = NSDictionaryResultType;
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"dayDate < %@", [NSDate todayDate]];
NSExpression *keyPathExpression = [NSExpression expressionForEvaluatedObject];
NSExpression *countExpression = [NSExpression expressionForFunction:@"count:" arguments:@[keyPathExpression]];
NSExpressionDescription * expressionDescription = [NSExpressionDescription new];
expressionDescription.name = @"eventsCount";
expressionDescription.expression = countExpression;
expressionDescription.expressionResultType = NSInteger32AttributeType;
NSEntityDescription *entity = [NSEntityDescription entityForName:@"SWEvent" inManagedObjectContext:self.managedObjectContext];
NSDictionary *attributes = [entity attributesByName];
NSAttributeDescription *statusDescription = attributes[@"status"];
NSAttributeDescription *dayDateDescription = attributes[@"dayDate"];
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"dayDate" ascending:NO];
request.predicate = predicate;
request.propertiesToFetch = @[calledDescription, dayDateDescription, statusDescription];
request.propertiesToGroupBy = @[dayDateDescription, statusDescription];
request.sortDescriptors = @[sortDescriptor];
NSError *error = nil;
@try {
NSArray *result = [self.managedObjectContext executeFetchRequest:request error:&error];
}
@catch(NSException *exception) {
NSLog(@"Exception occurred: %@, %@", exception, [exception userInfo]);
}
但是这段代码给了我这个,这显然是我不想要的,需要进一步过滤: `
{
status = 2;
eventsCount = 1;
dayDate = "2015-07-27 00:00:00 +0000";
},
{
status = 1;
eventsCount = 2;
dayDate = "2015-07-26 00:00:00 +0000";
},
{
status = 2;
eventsCount = 3;
dayDate = "2015-07-26 00:00:00 +0000";
}
`
有没有办法如何在一个查询中实现我需要的东西,或者我真的不能做得比这更好?
非常感谢
答案 0 :(得分:0)
这种情况的方法是在内核中执行,如“核心数据编程指南”中所建议的那样。我认为这会导致代码明显减少。如果你遇到任何性能或内存瓶颈会很有趣,但我会怀疑它。 (这应该在具有x0000记录的旧硬件上运行良好。)
NSArray *allDates = [allEvents valueForKeypath:@"dayDate"];
NSMutableArray *result = [NSMutableArray array];
for (NSDate *date in allDates) {
NSMutableDictionary *summary = [NSMutableDictionary dictionary];
NSArray *dayRecords = [allEvents filteredArrayUsingPredicate:
[NSPredicate predicateWithFormat:@"dayDate = %@", date]];
[summary addObject:@{"dayDate" : date}];
[summary addObject:@{"eventsCountTotal" : dayRecords.count}];
for (int x = 1; x <= 3; x++) {
NSArray *subgroup = [dayRecords filteredArrayUsingPredicate:
[NSPredicate predicateWithFormat:@"status = %i", x]];
[summary addObject:
@{[NSString stringWithFormat:@"status%iCount", %@] : @(subgroup.count)}]
}
[result addObject:summary]
}