0

我尝试为具有以下属性NSFetchRequest的实体设置和:Locationcountrycity

country  | city
————————————————
Germany  | Berlin
USA      | San Francisco
USA      | New York
Germany  | Munich
Germany  | Munich
USA      | San Francisco
Germany  | Stuttgart

NSFetchRequest应该返回国家(或具有适当国家的 Location 对象)和城市数量。

[
    { country: 'Germany', cityCount: 3 },
    { country: 'USA', cityCount: 2 }
]

我知道我可以获取所有条目并“自己计算”,但我对如何设置适当的获取请求(或者如果可以这样做)感兴趣,并且想看看你会怎么做!:)

4

2 回答 2

0

为了实现(我认为)你想要的,我不得不求助于两个单独的提取。country对于 和 的每个不同组合,第一次获取获取一个对象的 objectID city。使用IN谓词将第二次提取过滤到这些对象。它使用NSExpressionandpropertiesToGroupBy来获取每个的计数country

    // Step 1, get the object IDs for one object for each distinct country and city 
    var objIDExp = NSExpression(expressionType: NSExpressionType.EvaluatedObjectExpressionType)
    var objIDED = NSExpressionDescription()
    objIDED.expression = objIDExp
    objIDED.expressionResultType = .ObjectIDAttributeType
    objIDED.name = "objID"
    var fetch = NSFetchRequest(entityName: "Location")
    fetch.propertiesToFetch = [objIDED]
    fetch.propertiesToGroupBy = ["country", "city"]
    fetch.resultType = .DictionaryResultType
    let results = self.managedObjectContext!.executeFetchRequest(fetch, error: nil)

    // extract the objectIDs into an array...
    let objIDArray = (results! as NSArray).valueForKey("objID") as! [NSManagedObjectID];

    // Step 2, count using GROUP BY
    var countExp = NSExpression(format: "count:(SELF)")
    var countED = NSExpressionDescription()
    countED.expression = countExp
    countED.expressionResultType = .ObjectIDAttributeType
    countED.name = "count"
    var newFetch = NSFetchRequest(entityName: "Location")
    newFetch.predicate = NSPredicate(format: "SELF IN %@", objIDArray)
    newFetch.propertiesToFetch = ["country", countED]
    newFetch.propertiesToGroupBy = ["country"]
    newFetch.resultType = .DictionaryResultType
    let newResults = self.managedObjectContext!.executeFetchRequest(newFetch, error: nil)
    println("\(newResults!)")

这将是低效的:如果您有大量不同的国家和城市,IN 谓词会减慢速度。您可能会发现获取所有内容并计算它们的效率更高。

于 2015-08-29T17:42:12.850 回答
0

这个问题的正确答案是重构数据模型避免冗余

国家/地区字符串在表中不必要地重复。此外,您无缘无故地使一个简单的查询变得复杂。该模型应该反映您的数据,并且为每个美国城市写出“美国”既不聪明也不高效。

您的数据模型应如下所示

Country <----->> City

现在您可以获取所有国家/地区并使用cities.count.

于 2015-08-29T21:42:55.137 回答