基于列表属性的领域Swift过滤器查询

时间:2019-11-27 21:47:40

标签: swift realm realm-list realm-cloud

我需要一些有关领域快速查询的帮助。这是业务环境:

有两种用户类型:

用户类型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:艺术家

“艺术家”对象具有“ citysOfInterest”属性,并且应仅在应用程序上显示艺术家,该显示是由演出经理创建的,且演出城市位于该艺术家的“ citysOfInterest”中。然后,艺术家可以查看这些表演并做出响应,这将创建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的节目管理员在城市=“奥斯丁”的地方创建了一个节目 一位名叫吉姆(Jim)的艺术家的“ citysOfInterest =” [“奥斯汀”,“西雅图”,“旧金山”]

艺术家Jim进入应用程序,并应看到由节目经理Bob发布的新节目清单,因为Jim的citysInterest包含“ Austin”,并且节目所在的城市等于“ Austin”,并且没有artistResponse相关给吉姆。

我进行了研究,发现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”)

有人可以帮我吗?我希望我提供了足够的解释。

1 个答案:

答案 0 :(得分: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

我们想要的结果是,当艺术家吉姆登录时,他将看到孟菲斯的演出,因为他已经对奥斯丁的演出做出了回应。

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对象本身作为比较器。