2014-09-24 87 views
2

我有一个元素非常大的CoreData表像这样(简化):筛选功能实体描述

@interface Medicament : NSManagedObject 
@property (nonatomic, retain) NSString * identifier; 
@property (nonatomic, retain) NSString * name; 
@end 

在某些时候,我想找到的元素具有相同的性质(而丢弃其他),像这样的SQLite一句话:

SELECT name, COUNT(*) AS count FROM Medicament GROUP BY name WHERE count > 1 

为此,我有这样的CoreData查询:

NSFetchRequest* fetch = [NSFetchRequest fetchRequestWithEntityName:@"Medicament"]; 
NSEntityDescription* entity = [NSEntityDescription entityForName:@"Medicament" 
              inManagedObjectContext:self.managedObjectContext]; 
NSAttributeDescription* identifierDesc = [entity.attributesByName objectForKey:@"identifier"]; 
NSExpression *keyPathExpression = [NSExpression expressionForKeyPath: @"identifier"]; 
NSExpression *countExpression = [NSExpression expressionForFunction: @"count:" 
                  arguments: [NSArray arrayWithObject:keyPathExpression]]; 
NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init]; 
[expressionDescription setName: @"count"]; 
[expressionDescription setExpression: countExpression]; 
[expressionDescription setExpressionResultType: NSInteger32AttributeType]; 


[fetch setPropertiesToFetch:[NSArray arrayWithObjects:identifierDesc, expressionDescription, nil]]; 
[fetch setPropertiesToGroupBy:[NSArray arrayWithObject:identifierDesc]]; 
[fetch setResultType:NSDictionaryResultType]; 
NSError* error = nil; 
NSArray *results = [self.managedObjectContext executeFetchRequest:fetch 
                 error:&error]; 

这似乎正确返回字典列表,格式如下:

{ 
    count = 1; 
    identifier = 65023; 
}, 
    { 
    count = 2; 
    identifier = 65025; 
}, 
{ 
    count = 1; 
    identifier = 65027; 
} 

的问题是,我要放弃所有等于count1结果。

我已经尝试添加一个谓词来抓取希望CoreData是这样的聪明:

NSPredicate* predicate = [NSPredicate predicateWithFormat:@"count > 1"]; 
fetch.predicate = predicate; 

但它与错误keypath count not found in entity <NSSQLEntity Medicament id=11>崩溃。

这甚至可能使用CoreData或从数据库中提取后是否必须过滤结果?


这是我目前用于过滤对象的方法从数据库中已经加载:

NSPredicate* filterPredicate = [NSPredicate predicateWithFormat:@"count > 1"]; 
NSArray* filteredResults = [results filteredArrayUsingPredicate:filterPredicate]; 

,但我希望这个简单的计算可​​以通过CoreData或SQLite的执行,这可能会更高效。

+0

您在这里做的是将谓词设置为实体设置为药剂的提取请求,因此药剂没有名为count的属性!您可以创建一个具有标识符和count属性的模型,并使用从coredata获得的结果填充它,然后使用此谓词过滤该模型的数组。所以是的,我认为你必须首先从coredata获取结果,然后过滤它们。 – 2014-09-24 17:24:08

+0

@NofelMahmood是的,那是一个无望的尝试。我猜数据库引擎会比我通过代码执行操作要快得多。目前数据库有30k行,大约28k将被丢弃。所以我会从数据库加载大量不需要的数据。 – redent84 2014-09-24 17:28:15

+0

您是否使用过NSFetchRequest的“havingPredicate”功能? – pbasdf 2014-09-24 17:29:22

回答

0

您可以做到这一点的唯一方法是首先获取数据,然后从那里通过计数进行过滤。

如果您希望可以向称为count的实体添加一个属性,然后您可以使用该谓词来筛选所需实体(在此情况下计数> 1),但是您需要在药剂中添加计数属性实体做到这一点。

+0

正如你在最后几行看到的那样,这就是我正在做的事情 – redent84 2014-09-25 11:01:00