Как считать в coredata (агрегация)?

Я изучаю основные данные и особенно работаю над агрегированием.

Текущее, что я хочу сделать: подсчитать количество записей из таблицы, которые находятся в отношениях ко многим с обратными отношениями по некоторым критериям.

В настоящее время я делаю это:

NSExpression *ex = [NSExpression expressionForFunction:@"count:" 
                                                 arguments:[NSArray arrayWithObject:[NSExpression expressionForKeyPath:@"ddname"]]];
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"ddtype == 'Home'"];
    NSExpressionDescription *ed = [[NSExpressionDescription alloc] init];
    [ed setName:@"countDDEvents"];
    [ed setExpression:ex];
    [ed setExpressionResultType:NSInteger16AttributeType];
    NSArray *properties = [NSArray arrayWithObject:ed];
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    [request setPredicate:pred];
    [request setPropertiesToFetch:properties];
    [request setResultType:NSDictionaryResultType];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"DDEvent" inManagedObjectContext:[self.currentAccount managedObjectContext]];
    [request setEntity:entity];
    NSArray *results = [[self.currentAccount managedObjectContext] executeFetchRequest:request error:nil]; 
    NSDictionary *dict = [results objectAtIndex:0];
    NSLog(@"Average birthdate for female heroes: %@", [dict objectForKey:@"countDDEvents"]);

Это от Джеффа Лемарша.

EDIT: и я нашел свое решение как

    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"ddtype == 'Home'"];
    [request setPredicate:pred];

    NSEntityDescription *entity = [NSEntityDescription entityForName:@"DDEvent" inManagedObjectContext:[self.currentAccount managedObjectContext]];
    [request setEntity:entity];

    NSError *error = nil;
    NSUInteger count = [[self.currentAccount managedObjectContext] countForFetchRequest:request error:&error];

Он работает хорошо. Но я хочу делать больше запросов такого типа за раз. Поэтому я думаю, что это не может быть предпочтительным способом подсчета.

ИЗМЕНИТЬ :

Поэтому я думаю, что подход был бы подходящим ????

Так может ли кто-нибудь сказать мне более эффективный предпочтительный способ сделать это.

Спасибо .


person harshalb    schedule 27.07.2010    source источник


Ответы (2)


Джефф Ламарш просто использует это как простой пример. На практике эта потребность настолько распространена, что кодирование ключ-значение имеет встроенный макрос для обработки этого и других распространенных операций сбора.

См.: Руководство по программированию пар "ключ-значение": операторы множеств и массивов

В этом случае вы должны использовать оператор @count в своем предикате.

Конечно, ручная настройка вашего собственного выражения дает вам прекрасный контроль над вашими предикатами, но операторы справляются с 80% этой задачи.

person TechZen    schedule 27.07.2010

Мне пришлось подсчитать около 10 000 сущностей, и это сильно замедлило реакцию моего интерфейса, когда я делал это с помощью countForFetchRequest.

Вот способ сделать это с помощью NSExpression:

- (NSUInteger) unfilteredFCsCount {

// Just the fetchRequest
    NSFetchRequest *fetchRequest = [self unfilteredFCsFetchRequest];

    [fetchRequest setResultType: NSDictionaryResultType];

// You can use any attribute of the entity. its important, because you are not counting 
// the properties, but actually the entities
    NSExpression *keyPathExpression = [NSExpression expressionForKeyPath: @"sortIndex_"]; // Does not really matter
    NSExpression *maxExpression = [NSExpression expressionForFunction: @"count:" 
                                                            arguments: [NSArray arrayWithObject:keyPathExpression]];
    NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init];
    [expressionDescription setName: @"fcCount"];
    [expressionDescription setExpression: maxExpression];
    [expressionDescription setExpressionResultType: NSInteger32AttributeType];

    [fetchRequest setPropertiesToFetch: [NSArray arrayWithObject:expressionDescription]];

    NSUInteger fcCount = 0;
    NSError *error = nil;
    NSArray *results = nil;
    results = [self.managedObjectContext executeFetchRequest: fetchRequest error: &error];
    KSLog(KSLogLevelDebug, @"unfilteredFCsCount results: %@", results);

    if([results count] > 0) {
        NSNumber *count = [[results objectAtIndex: 0] objectForKey: @"fcCount"];
        fcCount = [count intValue];
    }

    return fcCount;
}
person Kim    schedule 13.05.2011