CoreData 与子表达式聚合

Posted

技术标签:

【中文标题】CoreData 与子表达式聚合【英文标题】:CoreData aggregates with subexpressions 【发布时间】:2015-07-27 16:34:36 【问题描述】:

我在这里和任何地方都阅读了我在这个主题上找到的所有内容,但仍然不知道如何做我需要的。

我在核心数据数据库中有一个简单的事件对象,其属性类似于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";

`

有没有办法在一个查询中实现我所需要的,或者我真的不能做得比这更好?

非常感谢

【问题讨论】:

【参考方案1】:

按照 Core Data Programming Guide 中的建议,这种情况下的方法是在内存中进行。我认为它会显着减少代码。如果您遇到任何性能或内存瓶颈会很有趣,但我会怀疑。 (这应该在具有 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]

【讨论】:

这基本上是我到目前为止的最终结果,但我想知道是否有一种方法可以直接在 CoreData 层上更有效地完成它。看来确实没有办法,所以我接受你的回答。谢谢。

以上是关于CoreData 与子表达式聚合的主要内容,如果未能解决你的问题,请参考以下文章

5.2.1 正则表达式语法与子模式扩展语法

maven maven项目构建ssh工程(父工程与子模块的拆分与聚合)

转帖:maven maven项目构建ssh工程(父工程与子模块的拆分与聚合)

CoreData NSPredicate MATCHES 正则表达式

ThetaSome_ThetaAll子查询

从零开始学习Oracle数据库函数与子查询和连接查询