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

この質問に対する正解は、冗長性を避けるためにデータ モデルをリファクタリングすることです。

テーブル内で国の文字列が不必要に繰り返されています。さらに、単純なクエリが不当に複雑になります。モデルはデータを反映する必要があり、アメリカのすべての都市を「USA」と書き出すのは賢明でも効率的でもありません。

データモデルは次のようになります

Country <----->> City

これで、すべての国を取得して、 で都市を取得できますcities.count

于 2015-08-29T21:42:55.137 に答える
0

あなたが望むものを達成するために(私が思うに)、2つの別々のフェッチに頼らなければなりませんでした。country最初のフェッチでは、との個別の組み合わせごとに 1 つのオブジェクトの objectID を取得しcityます。2 番目のフェッチは、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 述語は速度を低下させます。すべてをフェッチしてカウントする方が効率的であることに気付くかもしれません。

于 2015-08-29T17:42:12.850 に答える