按一个 属性 分组,同时使用核心数据检索更多
Group by one property while retrieving more with core data
我在 Core Data 中有一个 table 具有以下属性:
date, name, phone
我想检索一个包含 5 个唯一 phone 号码的列表,这些号码的名称按日期排序。所以在 MySQL 中它会是这样的:
SELECT name, phone FROM myTable GROUP BY phone ORDER BY date
所以如果我有这个数据列表:
01/23/2015 someName1 12345678
01/21/2015 someName2 12345678
01/21/2015 someOtherName1 987654321
我想检索一个唯一的 phone 号码列表,日期字段控制哪个名称与任何重复的号码相关联。在这种情况下,期望的结果将是:
01/23/2015 someName1 12345678
01/21/2015 someOtherName1 987654321
然而,使用 NSFetchRequest
执行此操作似乎有点复杂,因为 setPropertiesToGroupBy
需要包含与 setPropertiesToFetch
中定义的相同的属性列表。
换句话说,这就是我认为我能够做到的方式:
NSEntityDescription *entity = [NSEntityDescription entityForName:@"someEntity" inManagedObjectContext:someContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entity];
[request setResultType:NSDictionaryResultType];
[request setPropertiesToFetch:@[@"name", @"phone"]];
[request setPropertiesToGroupBy:@[@"phone"]];
[request setFetchLimit:5];
NSSortDescriptor *sortByCreatedDate = [[NSSortDescriptor alloc] initWithKey:@"date" ascending:NO];
[request setSortDescriptors:@[sortByCreatedDate]];
但是,除非我也包含 name
字段,否则 propertiesToGroupBy
会出现异常。
如何在不手动浏览列表的情况下实现我想要的?
附带条件是我认为这会起作用;就留给你去死死的测试吧:
除 propertiesToGroupBy
中的属性外,您无法向 propertiesToFetch
添加任何其他属性,但您似乎可以在要获取的属性中包含 objectID
。为此,为 "evaluated object":
构建一个 NSExpression
并关联 NSExpressionDescription
NSExpression *selfExp = [NSExpression expressionForEvaluatedObject];
NSExpressionDescription *selfED = [[NSExpressionDescription alloc] init];
selfED.name = @"objID";
selfED.expression = selfExp;
selfED.expressionResultType = NSObjectIDAttributeType;
现在定义另一个 expression/description 以获得最大值(日期):
NSExpression *maxDate = [NSExpression expressionForKeyPath:@"date"];
NSExpression *indexExp = [NSExpression expressionForFunction:@"max:" arguments:@[maxDate]];
NSExpressionDescription *maxED = [[NSExpressionDescription alloc] init];
maxED.name = @"maxDate";
maxED.expression = indexExp;
maxED.expressionResultType = NSDateAttributeType;
然后将这两个表达式描述包含在要获取的属性列表中:
[request setPropertiesToFetch:@[@"phone", maxED, selfED]];
[request setPropertiesToGroupBy:@[@"phone"]];
当您 运行 提取时,结果数组中的每一项都会有一个键 "objID",其中包含相关对象的对象 ID。您可以解压它,以访问名称 phone 等,使用以下内容:
NSArray *results = [self.context executeFetchRequest:request error:&error];
for (NSDictionary *dict in results) {
NSDate *maxDate = dict[@"maxDate"];
NSString *phone = dict[@"phone"];
NSManagedObjectID *objID = [dict valueForKey:@"objID"];
NSManagedObject *object = [self.context objectWithID:objID];
NSString *name = [object valueForKey:@"name"];
}
我不确定的一个特定方面是,如果两行具有完全相同的 date
.
,这将如何表现
我在 Core Data 中有一个 table 具有以下属性:
date, name, phone
我想检索一个包含 5 个唯一 phone 号码的列表,这些号码的名称按日期排序。所以在 MySQL 中它会是这样的:
SELECT name, phone FROM myTable GROUP BY phone ORDER BY date
所以如果我有这个数据列表:
01/23/2015 someName1 12345678
01/21/2015 someName2 12345678
01/21/2015 someOtherName1 987654321
我想检索一个唯一的 phone 号码列表,日期字段控制哪个名称与任何重复的号码相关联。在这种情况下,期望的结果将是:
01/23/2015 someName1 12345678
01/21/2015 someOtherName1 987654321
然而,使用 NSFetchRequest
执行此操作似乎有点复杂,因为 setPropertiesToGroupBy
需要包含与 setPropertiesToFetch
中定义的相同的属性列表。
换句话说,这就是我认为我能够做到的方式:
NSEntityDescription *entity = [NSEntityDescription entityForName:@"someEntity" inManagedObjectContext:someContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entity];
[request setResultType:NSDictionaryResultType];
[request setPropertiesToFetch:@[@"name", @"phone"]];
[request setPropertiesToGroupBy:@[@"phone"]];
[request setFetchLimit:5];
NSSortDescriptor *sortByCreatedDate = [[NSSortDescriptor alloc] initWithKey:@"date" ascending:NO];
[request setSortDescriptors:@[sortByCreatedDate]];
但是,除非我也包含 name
字段,否则 propertiesToGroupBy
会出现异常。
如何在不手动浏览列表的情况下实现我想要的?
附带条件是我认为这会起作用;就留给你去死死的测试吧:
除 propertiesToGroupBy
中的属性外,您无法向 propertiesToFetch
添加任何其他属性,但您似乎可以在要获取的属性中包含 objectID
。为此,为 "evaluated object":
NSExpression
并关联 NSExpressionDescription
NSExpression *selfExp = [NSExpression expressionForEvaluatedObject];
NSExpressionDescription *selfED = [[NSExpressionDescription alloc] init];
selfED.name = @"objID";
selfED.expression = selfExp;
selfED.expressionResultType = NSObjectIDAttributeType;
现在定义另一个 expression/description 以获得最大值(日期):
NSExpression *maxDate = [NSExpression expressionForKeyPath:@"date"];
NSExpression *indexExp = [NSExpression expressionForFunction:@"max:" arguments:@[maxDate]];
NSExpressionDescription *maxED = [[NSExpressionDescription alloc] init];
maxED.name = @"maxDate";
maxED.expression = indexExp;
maxED.expressionResultType = NSDateAttributeType;
然后将这两个表达式描述包含在要获取的属性列表中:
[request setPropertiesToFetch:@[@"phone", maxED, selfED]];
[request setPropertiesToGroupBy:@[@"phone"]];
当您 运行 提取时,结果数组中的每一项都会有一个键 "objID",其中包含相关对象的对象 ID。您可以解压它,以访问名称 phone 等,使用以下内容:
NSArray *results = [self.context executeFetchRequest:request error:&error];
for (NSDictionary *dict in results) {
NSDate *maxDate = dict[@"maxDate"];
NSString *phone = dict[@"phone"];
NSManagedObjectID *objID = [dict valueForKey:@"objID"];
NSManagedObject *object = [self.context objectWithID:objID];
NSString *name = [object valueForKey:@"name"];
}
我不确定的一个特定方面是,如果两行具有完全相同的 date
.