过滤器返回具有匹配子项的父级的所有子项

时间:2017-05-25 21:29:36

标签: swift realm filtering nspredicate

我使用Realm for Swift,我的结构如下:

class Navigation: Object {

    dynamic var key = 0
    dynamic var title: String?
    let companies = List<Companies>()

    override static func primaryKey() -> String? {
        return "key"
    }
}

class Companies: Object {

    dynamic var key = 0
    dynamic var name: String?
    let locations = List<Locations>()

    override static func primaryKey() -> String? {
        return "key"
    }
}

class Locations: Object {

    dynamic var key = 0
    ...
    dynamic var zip: String?
    let contacts = List<Contacts>()

    override static func primaryKey() -> String? {
        return "key"
    }
}

class Contacts: Object {

    dynamic var key = 0
    dynamic var firstName: String?
    dynamic var lastName: String?
    ...

    override static func primaryKey() -> String? {
        return "key"
    }
}

我尝试按邮政编码过滤掉地点,以便只显示与给定邮政编码匹配的地点。我是这样做的

companies = realm.objects(Navigation.self).filter("key = 4").first!.companies.filter(predicate).sorted(byKeyPath: "key")

key = 4位是因为过滤器只能在一个特定类别下的公司中搜索。

我遇到的问题是,它会返回具有匹配位置的公司的所有位置。因此,如果我找到的拉链是12345,并且公司A的位置匹配,则返回公司A下的所有位置,即使它们不匹配。

如何将结果限制为匹配的位置?

1 个答案:

答案 0 :(得分:3)

  

如何将结果限制为匹配的位置?

现在您正在返回Results<Companies>,但似乎您想要位置。通过向CompaniesLocations模型添加一些反向关系属性,我完成了我认为您正在寻找的内容,然后查询领域Locations匹配zip == '12345' && ANY parentCompanies.parentNavigation.key == 4。< / p>

这是一个演示此内容的示例应用:

import UIKit
import RealmSwift

class Navigation: Object {

    dynamic var key = 0
    dynamic var title: String?
    let companies = List<Companies>()

    override static func primaryKey() -> String? {
        return "key"
    }
}

class Companies: Object {

    dynamic var key = 0
    dynamic var name: String?
    let locations = List<Locations>()
    let parentNavigation = LinkingObjects(fromType: Navigation.self, property: "companies")

    override static func primaryKey() -> String? {
        return "key"
    }
}

class Locations: Object {

    dynamic var key = 0
    // ...
    dynamic var zip: String?
    let contacts = List<Contacts>()
    let parentCompanies = LinkingObjects(fromType: Companies.self, property: "locations")

    override static func primaryKey() -> String? {
        return "key"
    }
}

class Contacts: Object {

    dynamic var key = 0
    dynamic var firstName: String?
    dynamic var lastName: String?
    // ...

    override static func primaryKey() -> String? {
        return "key"
    }
}

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        _ = try? FileManager.default.removeItem(at: Realm.Configuration.defaultConfiguration.fileURL!)
        let realm = try! Realm()

        // Objects Matching Query
        try! realm.write {
            // Locations
            let locations = Locations()
            locations.zip = "12345"

            // Companies
            let companies = Companies()
            companies.name = "Companies A"
            companies.locations.append(locations)

            // Nav
            let nav = Navigation()
            nav.key = 4
            nav.companies.append(companies)

            // Add to Realm
            realm.add(nav)
        }

        let locationsIn12345AndNavigationKey4 = realm.objects(Locations.self)
            .filter("zip == '12345' && ANY parentCompanies.parentNavigation.key == 4")
        print(locationsIn12345AndNavigationKey4)

        return true
    }
}

打印:

Results<Locations> (
  [0] Locations {
    key = 0;
    zip = 12345;
    contacts = RLMArray <0x6000000f2100> (

    );
  }
)