【问题标题】:Realm Swift Filter Query Based On List Property基于 List 属性的 Realm Swift 过滤查询
【发布时间】:2019-11-27 21:47:40
【问题描述】:

我需要一些有关领域快速查询的帮助。以下是业务背景:

有两种用户类型:

用户类型 1:节目经理

节目经理可以创建节目。您将在下面找到 Show 对象的必要详细信息。如您所见,每个节目都有一个属性 artistResponses,它是 ArtistResponse 的列表。

class Show: Object {
    @objc dynamic var id = UUID().uuidString
    @objc dynamic var createdDate = Date()
    @objc dynamic var showManager: ShowManager!
    @objc dynamic var venueName = ""
    @objc dynamic var city = ""
    ...
    **let artistResponses = List<ArtistResponse>()**

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

    ... 
}

用户类型 2:艺术家

Artist 对象具有 cityOfInterest 属性,并且应用程序上的艺术家只能显示由节目经理创建的节目,其中节目城市位于艺术家的itiesOfInterest 中。然后,艺术家可以查看这些节目并做出回应,这将创建一个 ArtistResponse 对象并将其添加到上面在 Show 对象中看到的列表中。您将在下面找到 Artist 以及 ArtistResponse 对象的必要详细信息。

class Artist: Object {
    @objc dynamic var id = UUID().uuidString
    @objc dynamic var createdDate = Date()
    **let citiesOfInterest = List<String>()**
}
class ArtistResponse: Object {
    @objc dynamic var id = UUID().uuidString
    @objc dynamic var createdDate = Date()
    @objc dynamic var show: Show!
    @objc dynamic var artist: Artist!
    **@objc dynamic var available = true**

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

我遇到问题的查询与确定它是否是一个新节目有关(即艺术家没有与该节目关联的 ArtistResponse,将他们自己列为可用或不可用)。

这是一个例子:

一位名叫 Bob 的节目经理创建了一个节目,其中城市 = “Austin” 一位名叫 Jim 的艺术家有 cityOfInterest = [“Austin”, “Seattle”, “San Francisco”]

艺术家 Jim 进入应用程序,应该会看到演出经理 Bob 发布的这个新演出列表,因为 Jim 的 cityOfInterest 包含“Austin”并且演出的城市等于“Austin”,并且没有相关的艺术家回复给吉姆。

我研究并发现 Realm 中的列表存在限制。

https://forum.realm.io/t/predicate-to-search-in-field-of-type-list/733 https://github.com/realm/realm-cocoa/issues/5334

请帮忙解决这个问题:

Realm.objects(Show.self).filter(“以某种方式确定artistResponses列表中没有与Jim相关的artistResponse”)

有人可以帮我解决这个问题吗?我希望我已经提供了足够的解释。

【问题讨论】:

    标签: swift realm realm-list realm-cloud


    【解决方案1】:

    让我重申一下这个问题;

    您希望艺术家能够查询城市中的所有新节目 他们对尚未回复的地方感兴趣。

    如果是这个问题,让我从一些简单的示例数据开始

    如果有兴趣,两位艺术家各自有两个城市

    let a0 = Artist()
    a0.name = "Jim"
    a0.citiesOfInterest.append(objectsIn: ["Austin", "Memphis"])
    
    let a1 = Artist()
    a1.name = "Henry"
    a1.citiesOfInterest.append(objectsIn: ["Austin", "Memphis"])
    

    然后是两场演出,每个城市一场

    let s0 = Show()
    s0.name = "Austin Show"
    s0.city = "Austin"
    
    let s1 = Show()
    s1.name = "Memphis Show"
    s1.city = "Memphis"
    

    但艺术家 a0 (Jim) 已响应 s0 (Austin) 节目

    let r0 = ArtistResponse()
    r0.show = s0
    r0.artist = a0
    r0.available = true
    
    s0.artistResponses.append(r0) //jim responded to the Austin show
    

    我们想要的结果是,当艺术家 Jim 登录时,他将看到孟菲斯秀,因为他已经响应了奥斯汀秀。

    let realm = try! Realm()
    if let jim = realm.objects(Artist.self).filter("name == 'Jim'").first {
       let myCities = jim.citiesOfInterest
       let showResults = realm.objects(Show.self)
                              .filter("city IN %@ AND !(ANY artistResponses.artist.name == 'Jim')", myCities)
       for show in showResults {
          print(show.name)
       }              
    }
    

    输出是

    Memphis Show
    

    我们首先将吉姆感兴趣的城市作为一个数组,然后我们过滤与这些感兴趣的城市相匹配但没有与吉姆相关联的艺术家响应的节目。此过滤器基于名称,但您可以使用 Artist id 甚至 Artist 对象本身作为比较器。

    【讨论】:

    • Jay,非常感谢您花时间回答我的问题。看起来很棒!发布后,我自己最终找到了解决方案。我很好奇您是否对两者之间更有效的查询有任何想法?这是我的查询:newShowListings = Constants.realm.objects(Show.self).filter( """ NOT ANY artistResponses.artist.id == %@ AND city IN %@ AND showDate &gt;= %@ AND isCancelled == %@ AND draft == %@ """, availabilityTabBar.dbUser.id, citiesOfInterest, today, false, true)
    • 为了简洁起见,我在初始示例中没有提到一些额外的查询参数。
    • 好问题。你测试过 Realm 是如何解析过滤器的吗?例如,不是应用于整个查询还是仅应用于第一部分。 (NOT ANY artistResponses.artist.id == %@) AND ... 将不同于“不是(所有查询)”。另外,如果答案对您有帮助或者是另一种选择,请务必接受它,以便对其他人有所帮助。
    • 仔细看,我们的两个查询是等价的。您只是在使用“!”语法,而我使用的是 NOT。我赞成你的回答。感谢您花时间回复!
    • @JackJohnson 尽管您的涉及更多属性,但它们是相似的 - 只是好奇的是 NOT 仅适用于查询的第一部分,或者 NOT 是整个事情。顺便提一句。如果您觉得有帮助,您也可以接受答案。见How To Accept
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-26
    • 2015-02-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多