iOS:如何获取核心数据中具有最大计数的对象?

时间:2015-02-25 11:05:56

标签: ios core-data nspredicate aggregation nsfetchrequest

我的核心数据模型中有两个类,以及它的一对多关系。

让我们拿 Class Album< --->>类歌曲的解释。现在,我想从Album中获取(顶部)五张专辑,这些专辑的最大编号为Songs

Class Album
{
    albumID (Integer)
    name    (String)
    songs   (class B)
}

Class Songs
{
    name   (String)
    length (Integer)
}

@class Songs;
@interface Album : NSManagedObject

@property (nonatomic, retain) NSNumber * albumID;
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSSet *songs;

@end

@interface Album (CoreDataGeneratedAccessors)
- (void)addSongsObject:(Songs *)value;
- (void)removeSongsObject:(Songs *)value;
- (void)addSongs:(NSSet *)values;
- (void)removeSongs:(NSSet *)values;
@end

@class Album;

@interface Songs : NSManagedObject

@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSNumber * length;
@property (nonatomic, retain) Album *owner;

@end

这就是我正在尝试的,

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:[NSEntityDescription entityForName:@"Albums" inManagedObjectContext:[self context]]];
fetchRequest.fetchOffset = 0;
fetchRequest.fetchLimit = 5;
fetchRequest.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"albumID" ascending:YES]];
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"SELF @max.@count.songs"];
NSError *error = nil;
NSArray *albums = [[self context] executeFetchRequest:fetchRequest error:&error];

如果我没有传递谓词,它可以正常工作。但问题在于谓词。它会使应用程序崩溃,并显示以下消息:

  

***由于未捕获的异常'NSInvalidArgumentException'终止应用程序,原因:'无法解析格式   字符串“SELF @ max。@ count.songs”'

更新:我正在对NSExpression尝试同样但不能同时执行max:count:个功能?以下是我试过的,

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:[NSEntityDescription entityForName:@"Albums" inManagedObjectContext:[self context]]];

fetchRequest.fetchOffset = 0;
fetchRequest.fetchLimit = 5;

NSError *error = nil;

NSExpression *keyPathExpression = [NSExpression expressionForKeyPath:@"songs"];
NSExpression *countExpression = [NSExpression expressionForFunction:@"count:" arguments:[NSArray arrayWithObject:keyPathExpression]];
//NSExpression *maxExpression = [NSExpression expressionForFunction:@"max:" arguments:[NSArray arrayWithObject:keyPathExpression]];

NSExpressionDescription *maxCountExpressionDescription = [[NSExpressionDescription alloc] init];
[maxCountExpressionDescription setName:@"squishes"];
[maxCountExpressionDescription setExpression:countExpression];

[fetchRequest setPropertiesToFetch:[NSArray arrayWithObject:maxCountExpressionDescription]];
[fetchRequest setResultType:NSDictionaryResultType];

NSArray *albums = [[self context] executeFetchRequest:fetchRequest error:&error];

我想,我需要像这样查询,

  

SELECT album.name,max(count(album.songs))FROM Album;

如何在NSFetchRequest中创建此类查询,是否可以使用NSExpressionNSPredicate

2 个答案:

答案 0 :(得分:0)

尝试删除:

fetchRequest.predicate = [NSPredicate predicateWithFormat:@"SELF @max.@count.songs"];

并将您的排序描述符替换为:

fetchRequest.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"songs.@count" ascending:NO]];

答案 1 :(得分:0)

我以不同的方式解决了这个问题,我在Album类中添加了songsCount属性。每次我从相册中添加/删除歌曲时,我都会递增/递减它。然后我按照songsCount按降序排序所有相册。

一旦我可以获取所有专辑,我将运行for循环并取出前五个对象。

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:[NSEntityDescription entityForName:@"Albums" inManagedObjectContext:[self context]]];
fetchRequest.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"songsCount" ascending:NO]];
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"songsCount > 0"];
NSError *error = nil;
NSArray *albums = [[self context] executeFetchRequest:fetchRequest error:&error];
NSMutableArray *top5Albums = [NSMutableArray array];
NSInteger totalCounts = [albums count];
NSInteger maxIndex = (totalCounts >= 5) ? 5 : totalCounts;
for(NSInteger index = 0; index < maxIndex; index++) {
    [top5Albums addObject:[albums objectAtIndex:index]];
}