Запрос фильтра Realm Swift на основе свойства списка
Мне нужна помощь с быстрым запросом области. Вот бизнес-контекст:
Есть два типа пользователей:
Тип пользователя 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 есть свойство citiesOfInterest, и исполнителям в приложении следует показывать только шоу, созданные менеджерами шоу, в которых город шоу находится в группах citiesOfInterest исполнителя. Затем художник может просматривать эти шоу и отвечать, что создает объект ArtistResponse и добавляет его в список, показанный выше в объекте Show. Ниже вы найдете необходимые сведения о художнике, а также об объекте 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, связанного с выставкой, в которой указано, что оно доступно или недоступно).
Вот пример:
Менеджер шоу по имени Боб создает шоу, в котором город = "Остин". У артиста по имени Джим есть citiesOfInterest = ["Остин", "Сиэтл", "Сан-Франциско"]
Джим, художник, заходит в приложение и должен увидеть этот новый список выставок, опубликованный Бобом, менеджером шоу, потому что в файле citiesOfInterest Джима указано "Остин", а город шоу совпадает с "Остин", и нет ответа 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 нет ответа исполнителя, который связан с Джимом")
Может кто-нибудь помочь мне с этим? Надеюсь, я дал достаточно объяснений.
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 (Джим) отреагировал на шоу s0 (Остин)
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
Сначала мы получаем города интереса Джима в виде массива, затем мы фильтруем шоу, которые соответствуют этим городам интереса, но в которых нет ответов артистов, связанных с Джимом. Этот фильтр был основан на имени, но вы могли использовать идентификатор исполнителя или даже сам объект художника в качестве компаратора.