Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cassandra/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Core data 按对象ID对请求进行分组_Core Data_Nsfetchrequest - Fatal编程技术网

Core data 按对象ID对请求进行分组

Core data 按对象ID对请求进行分组,core-data,nsfetchrequest,Core Data,Nsfetchrequest,我需要返回一个对象列表及其相关对象的计数。在单个字典获取请求中似乎不可能做到这一点,因为我无法按objectID对获取结果进行分组 let objectIDExpression = NSExpressionDescription() objectIDExpression.name = "objectID" objectIDExpression.expression = NSExpression.expressionForEvaluatedObject() objectIDExpression.e

我需要返回一个对象列表及其相关对象的计数。在单个字典获取请求中似乎不可能做到这一点,因为我无法按objectID对获取结果进行分组

let objectIDExpression = NSExpressionDescription()
objectIDExpression.name = "objectID"
objectIDExpression.expression = NSExpression.expressionForEvaluatedObject()
objectIDExpression.expressionResultType = NSAttributeType.ObjectIDAttributeType

let countExpression = NSExpressionDescription()
countExpression.name = "count"
countExpression.expression = NSExpression(forFunction: "count:", arguments: [NSExpression(forKeyPath: "entries")])
countExpression.expressionResultType = .Integer32AttributeType

let fetchRequest = NSFetchRequest(entityName: "Tag")
fetchRequest.resultType = .DictionaryResultType
fetchRequest.propertiesToFetch = [objectIDExpression, countExpression]
fetchRequest.propertiesToGroupBy = [objectIDExpression]

var error: NSError?
if let results = self.context.executeFetchRequest(fetchRequest, error: &error) {
    println(results)
}
执行此请求时,会出现以下错误:

'Invalid keypath expression ((<NSExpressionDescription: 0x7f843bf2d470>), name objectID, isOptional 1, isTransient 0, entity (null), renamingIdentifier objectID, validation predicates (
), warnings (
), versionHashModifier (null)
 userInfo {
}) passed to setPropertiesToFetch:'
“无效的键路径表达式((),名称objectID,等参变量1,isTransient 0,实体(null),重命名标识符objectID,验证谓词”(
),警告(
),versionHashModifier(null)
用户信息{
})传递给setPropertiesToFetch:'
我还测试了只传递
“objectID”
表达式名,但这也失败了


因此,是否无法按对象ID分组?

使用
NSFetchedResultsController
可能更容易。您可以将
sectionNameKeyPath
设置为group,并使用生成的
nsindepath
s构建字典

也就是说,我认为按objectID分组没有任何意义,因为根据定义,每个对象ID都是唯一的。因此,每个组中将有一个实例。这可能就是设置
propertiesToGroupBy
失败的原因

所以,简短的回答是:不

例如


如果
entries
是可选的,则使用
tag.entries?.count??0

我玩了一会儿,肯定有办法通过主键将核心数据告知组

虽然我相信这是可能的,但我还是想不出来

我所能做的就是添加另一个独特的属性“uuid”(出于各种原因,我对我的所有实体都使用它)。使用
nsuid
可以很容易地做到这一点,也可以使用永久对象ID URI表示并将其转换为字符串

无论如何,我认为这可以满足您的需求,但是需要一个单独的惟一属性

fetchRequest.propertiesToGroupBy = @[@"uuid"];
我尝试了一系列的选择,如按属性分组,但
expressionForEvaluatedObject
总是呕吐,其他尝试都失败了

我相信你已经知道了。以防万一,尽管这至少是一个解决办法,即使你不把它用于其他任何事情,直到有人真正做到了这一点

FWIW,这是SQL

CoreData: sql: SELECT t0.Z_ENT, t0.Z_PK, COUNT( t1.Z_1ENTRIES), t0.ZUUID
    FROM ZTAG t0 LEFT OUTER JOIN Z_1TAGS t1 ON t0.Z_PK = t1.Z_2TAGS
    GROUP BY  t0.ZUUID
当然,必须有一种方法告诉它在GROUPBY子句中替换
t0.Z_PK
。我认为这应该是
expressionForEvaluatedObject
或“objectID”或“self”或“self.objectID”的一个简单特例


祝你好运,如果你解决了,请报告。我很感兴趣。

您无需使用
propertiesToGroupBy
即可获得所需的计数。CoreData似乎推断出了正确的计数范围,并使用了一个子选择(奇怪的是,只有在获取包含属性以及objectID和计数时,才使用,见下文)。例如,我有
标签
许多带有
项目的标签

第一次尝试

我可以获取
标记名
和项目计数,如下所示:

NSFetchRequest *fetch = [NSFetchRequest fetchRequestWithEntityName:@"Tag"];
NSExpressionDescription *countED = [NSExpressionDescription new];
countED.expression = [NSExpression expressionWithFormat:@"count:(items)"];
countED.name = @"countOfItems";
countED.expressionResultType = NSInteger64AttributeType;
fetch.resultType = NSDictionaryResultType;
fetch.propertiesToFetch = @[@"tagName", countED];
NSArray *results = [self.context executeFetchRequest:fetch error:nil];
NSLog(@"results is %@", results);
这将生成以下SQL:

SELECT t0.ZTAGNAME, (SELECT COUNT(t1.Z_3ITEMS) FROM Z_3TAGS t1 WHERE (t0.Z_PK = t1.Z_8TAGS) ) FROM ZTAG t0
第二次尝试

遗憾的是,如果我尝试选择objectID而不是标记名
,CoreData似乎会变得混乱:

NSExpressionDescription *selfED = [NSExpressionDescription new];
selfED.expression = [NSExpression expressionForEvaluatedObject];
selfED.name = @"self";
selfED.expressionResultType = NSObjectIDAttributeType;
fetch.resultType = NSDictionaryResultType;
fetch.propertiesToFetch = @[selfED, countED];
生成以下SQL:

SELECT t0.Z_ENT, t0.Z_PK, COUNT( t1.Z_3ITEMS) FROM ZTAG t0 LEFT OUTER JOIN Z_3TAGS t1 ON t0.Z_PK = t1.Z_8TAGS
它统计来自外部联接的所有行(并建议您需要按objectID分组,尽管我们知道这不起作用)

最后一次尝试

但是,包括标记名和objectID,一切都很好:

fetch.propertiesToFetch = @[selfED, @"tagName", countED];
给出:

SELECT t0.Z_ENT, t0.Z_PK, t0.ZTAGNAME, (SELECT COUNT(t1.Z_3ITEMS) FROM Z_3TAGS t1 WHERE (t0.Z_PK = t1.Z_8TAGS) ) FROM ZTAG t0
SELECT t0.Z_ENT, t0.Z_PK, (SELECT COUNT(t2.ZITEMNAME) FROM Z_3TAGS t1 JOIN ZITEMS t2 ON t1.Z_3ITEMS = t2.Z_PK WHERE (t0.Z_PK = t1.Z_8TAGS) ) FROM ZTAG t0
这似乎起到了作用。(很抱歉恢复到Objective-C,并使用不同的实体/属性名称,但我相信您已经了解了情况)

旁白

我发现的另一个好奇之处是,上述第二次尝试也可以通过计算关系的属性而不是关系本身来实现:

countED.expression = [NSExpression expressionWithFormat:@"count:(items.itemName)"];
fetch.propertiesToFetch = @[selfED, countED];
给出:

SELECT t0.Z_ENT, t0.Z_PK, t0.ZTAGNAME, (SELECT COUNT(t1.Z_3ITEMS) FROM Z_3TAGS t1 WHERE (t0.Z_PK = t1.Z_8TAGS) ) FROM ZTAG t0
SELECT t0.Z_ENT, t0.Z_PK, (SELECT COUNT(t2.ZITEMNAME) FROM Z_3TAGS t1 JOIN ZITEMS t2 ON t1.Z_3ITEMS = t2.Z_PK WHERE (t0.Z_PK = t1.Z_8TAGS) ) FROM ZTAG t0

如果
itemName
不是零,

看起来错误在
[NSExpression(forKeyPath:“Entries”)]
中,可能是指一个对多关系,根据核心数据规则,名称不能大写。抱歉,这是示例代码中的一个输入错误。我还详细阐述了错误消息。需要明确的是,只有在设置
propertiesToGroupBy
属性时才会发生错误。没有它,fetch可以工作,但是没有按每个“tag”对象进行分组。relatnioship是一个多,还是多个多?Ie一个条目可以有多个标签吗?@pbasdf标签和条目之间有很多关系。可惜。。。如果它是一个或多个,您只需获取
条目
并按
标记进行分组
。我想您可以显式地建模与中间实体的多对多关系,并在获取中使用该实体。但这是一个混乱的解决方案,需要对代码的其余部分进行大量更改。我不确定这是否对我的情况有帮助。我基本上需要一种有效的方法,将
Tag
对象映射到它有多少个相关
Entry
对象的整数计数。我不想简单地获取所有标记对象并计算关系集的大小,因为我不想将所有相关对象都放到上下文中,因为每个标记可能有数百个。我相信(尽管我可能错了)计算集合的大小会使相关对象出错。例如,
count(tag.entries)
参见我的修订答案。我认为关于对象ID有一些混淆。每个对象ID都是唯一的,所以我想按它分组。我想要一个字典数组,每个字典有2个键,objectID,以及与之相关的条目数,我认为使用FRC会非常有效。我看不出这些条目将如何消除错误。只需遍历
fetchedObjects
并获取
entries.count
。我在旧硬件上做过类似的事情,有10万条记录,比如第一台没有p