如何在Realm中调用关系属性的聚合函数?

时间:2016-01-27 23:24:49

标签: ios swift realm

有没有办法在一对一和一对多关系中使用属性的聚合函数?这是我使用的结构的简单示例:

class Toy: Object {
    dynamic var purchaseDate: NSDate?
    dynamic var name: String = ""
    let ratings = List<Rating>()
    dynamic var toyOwner: Person?
}

class Rating: Object {
    var stars: Int = 0
    var comments: String?
}

class Person: Object {
    dynamic var name: String = ""
    dynamic var age: Int = 0
}

我想按照以下方式做点什么:

// Average age of owner of all toys purchased within a date range
let avgAge: Double = realm.objects(Toy)
    .filter("purchaseDate >= %@ && purchaseDate <= %@", startDate, endDate)
    .avg("person.age")

// Sum up all stars given to all toys purchased within a date range
let totalStars: Double = realm.objects(Toy)
    .filter("purchaseDate >= %@ && purchaseDate <= %@", startDate, endDate)
    .sum("sum(ratings.stars)")

有没有办法在Realm中执行这些聚合功能?

1 个答案:

答案 0 :(得分:2)

尽管Realm确实具有聚合值函数(请参阅RealmCollectionType上的Aggregate Operations文档),但这些函数当前不适用于person.age等多级键路径。

但是,您可以通过稍微修改查询来完成Realm的大部分繁重任务:

// Average age of owner of all toys purchased within a date range
let ages = realm.objects(Toy)
    .filter("purchaseDate BETWEEN %@", [startDate, endDate])
    .valueForKeyPath("toyOwner.age") as! [Double]
let avgAge = ages.reduce(0, combine: +) / Double(max(ages.count, 1))

// Sum up all stars given to all toys purchased within a date range
let totalStars = realm.objects(Toy)
    .filter("purchaseDate BETWEEN %@", [startDate, endDate])
    .reduce(0) { sum, toy in
        return sum + toy.ratings.sum("stars")
}