按一个 属性 分组,同时使用核心数据检索更多

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.

,这将如何表现