2012-08-26 30 views
3

我無法理解如何最好地使用核心數據來解決這個問題,包括描述問題的正確術語。下面是該問題的說明性示例(但不是我的實際對象)。假設您有一個音樂播放系統,藝術家擁有歌曲,並且每次系統播放一首歌曲時,都會記錄時間戳。使用核心數據中的NSFetchRequest獲取聚合關係計數?

問題:如何找到播放歌曲的藝術家人數?

這裏有樣品NSManagedObject

@interface MYArtist : NSManagedObject 
@property (nonatomic, retain) NSString *name; 
@property (nonatomic, retain) NSSet *songs; 
@end 

@interface MYSong : NSManagedObject 
@property (nonatomic, retain) NSString *name; 
@property (nonatomic, retain) MYArtist *artist; 
@property (nonatomic, retain) NSSet *plays; 
@end 

@interface MYPlay : NSManagedObject 
@property (nonatomic, retain) NSDate *playDate; 
@property (nonatomic, retain) MYSong *song; 
@end 

下面是樣本數據,藝術家,歌曲和播放,包括播放日期:

A1 <-+-> S1_A1 <---> P1_S1_A1 (2012-08-31) 
    '-> S2_A1 <-+-> P1_S2_A1 (2012-08-31) 
       '-> P2_S2_A1 (2012-09-01) 
A2 <-+-> S1_A2 
    '-> S2_A2 <---> P1_S2_A2 (2012-08-31) 
A3 <---> S1_A3 

使用下面的代碼,我可以獲取所有MYPlay對象並建立一組藝術家,然後在最後找到該組的大小。從這個示例數據和代碼生成的集合將是[A1,A2],count = 2。但是,我期望某些NSPredicate語法或使用countForFetchRequest更有效,而不是迭代對象並將它們錯誤地存儲到內存中。

NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"MYPlay"]; 
NSArray *results = [managedObjectContext executeFetchRequest:fetchRequest error:&error]; 

NSMutableSet *set = [[NSMutableSet alloc] init]; 
for (id result in results) { 
    MYPlay *play = (MYPlay *)result; 
    [set addObject:play.song.artist]; 
} 

NSUInteger count = set.count; 

回答

4

的記錄不SUBQUERY可能是一個很好的解決方案,你可以嵌套他們,你可以檢查協會的協會。

所以:

NSFetchRequest * request = [NSFetchRequest fetchRequestWithEntityName:@"MYArtist"]; 
request.predicate = [NSPredicate predicateWithFormat:@"(SUBQUERY(songs,$song,SUBQUERY($song.plays,$play,$play.playDate NOT NULL)[email protected] > 0)[email protected] >0)"]; // I'm assuming that songs with out a play have a nil playDate 

NSUInteger count = [context countForFetchRequest:request error:&error]; 

我沒有測試子查詢字符串,但應該讓你開始。如果你是Google的話,那裏有一些很好的資源,但在Apple文檔中沒有太多資源。文檔NSExpression指出「子查詢表達式的字符串格式爲:」

SUBQUERY(collection_expression,variable_expression,predicate);

1

你可以試試這個: 獲取歌曲獨特的藝術家的名字與播放次數超過0.1

NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"MYSong"]; 
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"[email protected] > 0"]; 
    [request setPredicate:predicate]; 
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"MYSong" inManagedObjectContext:context]; 
    NSDictionary *entityProperties = [entity propertiesByName]; 
    [request setReturnsDistinctResults:YES]; 
    [request setPropertiesToFetch:[NSArray arrayWithObject:[entityProperties objectForKey:@"artist"]]]; 

    NSError *error = nil; 
    NSArray *result = [managedObjectContext executeFetchRequest:request error:&error]; 

查看更多獨特的數據結果獲取: Retrieving a unique result set with Core Data