关于领域:反向关系查询

Query on inverse relationship

我是 Realm 的新手,遇到的查询问题让我疯狂了好几天。我有 2 个简单的类 Dog 和 Person 作为:

1
2
3
4
5
6
7
8
9
10
11
12
class Dog: Object {
    dynamic var dogName =""
    dynamic var dogAge = 1
    var owners: [Person] {
       return linkingObjects(Person.self, forProperty:"dogs")
    }
}

class Person: Object {
    dynamic var firstName =""
    let dogs = List<Dog>()
}

向Realm添加数据后,我有以下数据:

  • 奥斯卡有 3 只狗,分别是 A、B 和 C,年龄分别为 4 岁、6 岁和 9 岁
  • 詹妮弗有 3 只狗,分别是 D、E 和 F,年龄分别为 1、2 和 7
  • 一只名叫 Z 的狗,8 岁,没有主人。
1
2
3
4
5
6
7
8
9
10
let database = try! Realm()
// Query all Dogs- It should have 7 dogs
let allDogs = database.objects(Dog)
print("A total of \\(allDogs.count) dogs")   // 7 dogs - correct

// Query All dogs between age of 4 and 12 - there should be 5 dogs

let agedDogs = database.objects(Dog).filter("dogAge BETWEEN {4,12}")
print("Dogs between Age 4 and 12 = \\(agedDogs.count) \
")   // 5 dogs - OK

我想知道所有这些agedDog,其中有多少属于奥斯卡?
我试过了:

1
2
let specificOwnerAgedDogs = agedDogs.filter("ANY owners.firstName = 'Oscar'")
print("Oscar Dogs between Age 4 and 12 = \\(specificOwnerAgedDogs)")

但是这个查询导致错误:

Terminating app due to uncaught exception 'Invalid property name', reason: 'Property 'owners' not found in object of type 'Dog''

我正在使用 Realm Swift 和 Swift 2.1.1。


Realm Swift 还不支持为遍历反向关系的查询提供直接支持,例如 Dog 类上的 owners 属性。这是我们正在做的事情,应该会在不久的将来成为 Realm Swift 版本。

现在,你可以通过在 Swift 中而不是在谓词中执行一些过滤来解决这个限制:

1
2
3
4
let specificOwners = database.objects(Person).filter("firstName = 'Oscar'")
let specificOwnerAgedDogs = specificOwners.flatMap() { owner in
    owner.dogs.filter() { $0.dogAge >= 4 && $0.dogAge <= 12 }
}


1
2
3
4
let noOwn = agedDogs.flatMap {
   (ndog) -> Dog? in
   ndog.owners == [] ? ndog : nil
}

我用这个代码找出所有没有任何主人的老狗的列表?
对此有什么想法吗?