筛选功能实体描述
问题描述:
我有一个元素非常大的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;
}
的问题是,我要放弃所有等于count
到1
结果。
我已经尝试添加一个谓词来抓取希望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的执行,这可能会更高效。
答
您可以做到这一点的唯一方法是首先获取数据,然后从那里通过计数进行过滤。
如果您希望可以向称为count的实体添加一个属性,然后您可以使用该谓词来筛选所需实体(在此情况下计数> 1),但是您需要在药剂中添加计数属性实体做到这一点。
+0
正如你在最后几行看到的那样,这就是我正在做的事情 – redent84 2014-09-25 11:01:00
您在这里做的是将谓词设置为实体设置为药剂的提取请求,因此药剂没有名为count的属性!您可以创建一个具有标识符和count属性的模型,并使用从coredata获得的结果填充它,然后使用此谓词过滤该模型的数组。所以是的,我认为你必须首先从coredata获取结果,然后过滤它们。 – 2014-09-24 17:24:08
@NofelMahmood是的,那是一个无望的尝试。我猜数据库引擎会比我通过代码执行操作要快得多。目前数据库有30k行,大约28k将被丢弃。所以我会从数据库加载大量不需要的数据。 – redent84 2014-09-24 17:28:15
您是否使用过NSFetchRequest的“havingPredicate”功能? – pbasdf 2014-09-24 17:29:22