2015-08-29 61 views
0

我嘗試建立一個NSFetchRequest一個實體Location與屬性,如countrycityNSFetchRequest:查詢爲不同的值並計算其他屬性的值

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 } 
] 

我知道我可以獲取所有條目,「算我自己」,但我感興趣的是如何建立一個適當的取得請求(或者,如果有可能的話),想怎麼看你會做到的! :)

+0

這當然是可能的。你在使用Swift還是Objective-C? – pbasdf

+0

我在Swift中比Obj-C多,但我可以同時讀取;) – ItsTCalling

+0

我說得太快;要實現「獨特」要求並不容易,同時也要使用「group by」來計算。也許這就是你問的原因。 – pbasdf

回答

0

這個問題的正確答案是重構數據模型爲了避免冗餘

國家字符串在表中不必要地重複。另外,你可以做一個簡單的查詢,無需複雜。該模型應該反映你的數據,並且爲每個美國城市寫出「美國」並不聰明或者效率不高。

你的數據模型看起來應該像這樣

Country <----->> City 

現在你可以獲取所有國家,並與cities.count獲得城市。

+0

我使用這種方法...但有時你沒有這個機會;) – ItsTCalling

0

我不得不訴諸兩個單獨的提取爲了實現(我認爲)你想要什麼。第一次獲取獲取countrycity的每個不同組合的一個對象的objectID。第二次提取使用謂詞,僅針對這些對象進行過濾。它採用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謂詞會慢下來。您可能會發現獲取所有內容並對其進行計數效率更高。

+0

我從來沒有使用IN謂詞,這確實是一個非常酷的方法。我希望在一個NSFetchRequest中可以實現...。如果下週沒有其他解決方案,我會接受你的答案!非常感謝! :) – ItsTCalling

+0

該解決方案比使用KVC在內存中獲取和分析的效率更高,效率更低。 – Mundi

相關問題