Как рассчитывать в coredata (агрегация)?
Я изучаю основные данные и особенно работаю над агрегацией.
Current что я хочу сделать:подсчитайте количество записей из таблицы, которая находится в отношении ко многим с обратной связью по некоторым критериям.
В настоящее время я делаю это:
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"]);
С Джефф lemarche.
редактировать: и я нашел свое решение как
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];
он работает хорошо .Но Я хочу сделать больше запросов такого типа за один раз . Поэтому я думаю, что это не может быть предпочтительным способом получения графа .
редактировать :
поэтому я думаю, что подход будет подходящим ????
Так может ли кто-нибудь сказать мне более эффективный предпочтительный способ сделать это .
спасибо .
2 ответов
Джефф Ламарш просто использует это в качестве простого примера. На практике эта потребность настолько распространена, что в Кодирование значений ключей встроен макрос для обработки и других общих операций сбора данных.
посмотреть: руководство по программированию ключевых значений: операторы Set и Array
в этом случае вы должны использовать @count
оператор в своем предикате.
конечно, ручная настройка вашего собственного выражения дает вам прекрасный контроль над вашими предикатами, но операторы справляются с 80% такой задачи.
мне пришлось сосчитать около 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;
}