NSFetchRequest:查询不同的值并计算其他属性值

时间:2015-08-29 10:16:55

标签: core-data nspredicate nsfetchrequest nsexpression

我尝试使用NSFetchRequestLocation等属性为实体country设置city

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

NSFetchRequest应该返回国家/地区(或具有相应国家/地区的位置对象)和城市数量。

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

我知道我可以获取所有条目并“自己计算”,但我对如何设置适当的提取请求感兴趣(或者是否可以这样做),并希望看到你如何做到这一点! :)

2 个答案:

答案 0 :(得分:0)

为了实现(我想)你想要的东西,我不得不求助于两个单独的提取。第一次获取为countrycity的每个不同组合获取一个对象的objectID。第二次获取使用IN谓词过滤到这些对象。它使用NSExpressionpropertiesToGroupBy来获取每个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谓词将减慢速度。您可能会发现获取所有内容并计算它们的效率更高。

答案 1 :(得分:0)

重构数据模型以解决此问题的正确答案避免冗余

表格中不必要地重复国家字符串。另外,你做一个简单的查询无偿复杂。该模型应反映您的数据,并写出" USA"因为每个美国城市都不聪明或没有效率。

您的数据模型应如下所示

Country <----->> City

现在,您只需抓取所有国家/地区并使用cities.count获取城市。