2009-11-25 100 views
0

我有模型有字段日期。我需要獲取全年的所有記錄數,或者如果今天沒有記錄提取爲0.現在我獲取所有年份的記錄並用手製作。我可以使用核心數據查詢嗎?核心數據複雜查詢

回答

1

通常在Core Data中,執行所有抓取操作要快得多,而不是將其分解爲多個抓取。

我試着算在今年的一天記錄在兩個方面:

  1. 提取所有記錄的一年。爲這些記錄找到不同的日期。循環播放日期並對記錄進行計數。

  2. 在每年的每一天循環。對該日期的記錄執行僅計數提取。

對於一個小型數據庫(48條記錄),第一種方法的速度提高了90倍。我想,隨着更多記錄的添加,第一種方法的性能會變差,第二種方法會保持不變。

下面是代碼:

- (void)doFullLoadTestWithYear:(int)year { 
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 

NSEntityDescription *entity = [NSEntityDescription entityForName:@"Record" inManagedObjectContext:self.managedObjectContext]; 
[fetchRequest setEntity:entity]; 

NSCalendar *gregorian = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease]; 
NSDateComponents *comps = [[[NSDateComponents alloc] init] autorelease]; 
[comps setDay:1]; 
[comps setMonth:1]; 
[comps setYear:year]; 
NSDate *start = [gregorian dateFromComponents:comps]; 
[comps setDay:31]; 
[comps setMonth:12]; 
NSDate *end = [gregorian dateFromComponents:comps]; 

NSPredicate *yearPred = [NSPredicate predicateWithFormat:@"date >= %@ && date <= %@",start,end]; 
[fetchRequest setPredicate:yearPred]; 

NSError *error = nil; 
NSArray *array = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error]; 
[fetchRequest release]; 
if (error) { 
    NSLog(@"Error during fetch: %@",[error localizedDescription]); 
    abort(); 
} 
int dateCount = 0, recordCount = 0; 

NSArray *dates = [array valueForKeyPath:@"@distinctUnionOfObjects.date"]; 

for (NSDate *date in dates) { 
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"date == %@",date]; 

    NSArray *records = [array filteredArrayUsingPredicate:pred]; 

    dateCount++; 
    recordCount += [records count]; 

    NSLog(@"%d record(s) with date %@",[records count],date); 
} 

NSLog(@"Record count for year is %d",recordCount); 
NSLog(@"Distinct dates count is %d",dateCount); 
} 

- (void)doSeparateTestWithYear:(int)year { 
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 

NSEntityDescription *entity = [NSEntityDescription entityForName:@"Record" inManagedObjectContext:self.managedObjectContext]; 
[fetchRequest setEntity:entity]; 

NSCalendar *gregorian = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease]; 
NSDateComponents *comps = [[[NSDateComponents alloc] init] autorelease]; 
[comps setDay:1]; 
[comps setMonth:1]; 
[comps setYear:year]; 
NSDate *start = [gregorian dateFromComponents:comps]; 
[comps setYear:year+1]; 
NSDate *end = [gregorian dateFromComponents:comps]; 

NSDateComponents *oneDay = [[[NSDateComponents alloc] init] autorelease]; 
[oneDay setDay:1]; 

int dateCount = 0, recordCount = 0; 

NSDate *date = start; 
while (![date isEqual:end]) { 
    NSPredicate *dayPred = [NSPredicate predicateWithFormat:@"date == %@",date]; 
    [fetchRequest setPredicate:dayPred]; 

    NSError *error = nil; 
    int count = [self.managedObjectContext countForFetchRequest:fetchRequest error:&error]; 
    if (error) { 
    NSLog(@"Error during fetch: %@",[error localizedDescription]); 
    abort(); 
    } 

    if (count > 0) { 
    NSLog(@"%d record(s) with date %@",count,date); 
    dateCount++; 
    recordCount += count; 
    } 

    date = [gregorian dateByAddingComponents:oneDay toDate:date options:0]; 
} 

NSLog(@"Record count for year is %d",recordCount); 
NSLog(@"Distinct dates count is %d",dateCount); 

[fetchRequest release]; 
}