#swift #realm
#swift #realm
Вопрос:
Я создал два Realm Object
. Я хочу отфильтровать объект вложенного списка, но я не могу отфильтровать.
Мой первый объект, как показано ниже
class OrgDetails: Object, Codable {
@objc dynamic var orgId: Int = 0
//some other property
let orgMembers = List<OrgMembers>()
@objc dynamic var isRemoved: Bool = false
//other code
}
Мой второй объект
class OrgMembers: Object,Codable {
@objc dynamic var orgId: Int = 0
@objc dynamic var orgMemberId: Int = 0
@objc dynamic var isDeleted: Bool = false
//other property and code
}
здесь я пытаюсь выполнить приведенный ниже запрос для фильтрации результирующего набора. Я хочу выбрать только те orgMembers, которые не удалены вместе с его orgDetails.
let orgs = RealmManager.shared.read(condition: "isRemoved = false", object: OrgDetails.self)?.filter("orgMembers.isDeleted = false")
Я также пробовал это
self.corporates = RealmManager.shared.read(condition: "isRemoved == false and orgMembers.isDeleted == false", object: OrgDetails.self)?.toArray(type: OrgDetails.self)
Но оба запроса выдают ошибку
'Invalid predicate', reason: 'Key paths that include an array property must use aggregate operations'
Как я могу использовать фильтр для извлечения записей? Есть ли какой-либо другой способ достичь вышеуказанного результата?
Комментарии:
1. Если участник организации удален, но данные организации, к которой он принадлежит, не удалены, вы хотите, чтобы это было в результатах? (Похоже, вы не хотите, чтобы это было в результатах, но понимаете, что получаете
Results<OrgDetails>
, поэтому вы можете фильтровать только сведения об организации, а не членов организации)2. Вы пытаетесь получить массив OrgDetails или массив OrgMembers? Если это последнее, это одномерный или двумерный массив?
3. @rs7 Спасибо за ответ. Да, я пытаюсь получить массив OrgDetails вместе с OrgMembers.
4. @Sweeper Спасибо за ответ. Сценарий, который вы упомянули в комментарии, не будет выполнен. Итак, здесь я хочу получить OrgDetails вместе с его OrgMembers, которые не удаляются.
5. Вопрос немного неясен, но проблема в том, что вы не можете вернуть два разных объекта в результате — они однородны. например, если ваша цель — вернуть организации и члены, которые не удалены , как указано в вопросе, вы не можете. Вы можете возвращать организации или вы можете возвращать элементы, но не оба. Возможно, вы имеете в виду, что вы хотите запросить OrgDetails были isRemoved = false И имеет объект orgMembers, где IsDeleted = false? Возможно, было бы неплохо переосмыслить то, что задается, и прояснить вопрос.
Ответ №1:
Ваш вопрос неясен.
Если вам нужен список организаций, которые не были удалены И в которых нет удаленных участников, это даст вам то, что вы хотите:
let orgs = RealmManager.shared.read(condition: "isRemoved == false", object: OrgDetails.self)?
.filter("SUBQUERY(orgMembers, $orgMember, $orgMember.isDeleted == true).@count == 0")
Если вы хотите получить список организаций, которые не были удалены, опустив его элементы, которые были удалены, вы не можете сделать это с помощью запроса. Мое предложение состояло бы в том, чтобы определить вашу модель OrgDetails с двумя списками. Один список, содержащий элементы, которые не были удалены, и другой список с удаленными элементами.
class OrgDetails: Object, Codable {
@objc dynamic var orgId: Int = 0
let orgMembers = List<OrgMembers>()
let orgMembersDeleted = List<OrgMembers>()
@objc dynamic var isRemoved: Bool = false
}
Комментарии:
1. Спасибо за ваш ответ. Да, я хочу извлекать только те orgMembers, которые не удаляются. В одной организации много членов ORGM. Итак, я хочу пропустить тех участников, у которых есть
isDeleted == true
участники. Я пробовал ваш запрос, но он не возвращает никаких записей. У меня есть одна организация с несколькими членами orgMembers. Некоторые из них удалены, а другие нет.2. Запрос, который я вам дал, вернет только организации, у которых нет удаленных участников. Итак, если в вашей организации есть какие-либо удаленные участники, это не будет отображаться в результатах. Как я уже сказал, ваш вопрос был немного неясен. Но, надеюсь, это проясняет.
3. О, хорошо. Итак, есть ли какой-либо способ получить только те orgMember, которые не были удалены?
4. Как я уже говорил выше, у вас может быть либо два списка, либо один для удаленных участников, либо другой для не удаленных участников. Или вы можете просто отфильтровывать удаленных участников из orgMembers всякий раз, когда они вам понадобятся.
Ответ №2:
Позвольте мне повторить вопрос:
Основываясь на двух объектах Realm в вопросе, вы хотите вернуть все OrgDetails, где isRemoved = false, И ЛЮБЫЕ orgMembers в списке имеют свойство isRemoved = false .
Другими словами, если значение isRemoved равно false в главном свойстве, а все организационные элементы в списке имеют значение isRemoved = false.
Если это вопрос, то ответ однозначный
let result = realm.objects(OrgDetails.self).filter("isRemoved == false AND (ANY orgMembers.isDeleted == false)")
Это вернет все объекты OrgDetails, где isRemoved равно false, и любые OrgMembers в их свойстве List имеют IsDeleted = false.
Комментарии:
1. Спасибо за ответ. Я пробовал ваш запрос, но он также удален orgMembers. Я хочу пропустить все удаленные OrgMembers и хочу выбрать только не удаленных участников. В принципе, я хочу пропустить всех тех, у кого
isDeleted == true
2. @Ajay Это именно то, что делает мой ответ; возвращает все объекты OrgDetails, где isRemoved == false И где любой из объектов OrgMembers IsDeleted равен false. Другими словами; предположим, что свойство OrgDetails isRemoved равно false . Это означает, что это кандидат. Тогда предположим, что у OrgDetails есть свойство List с 10 orgMembers в нем. Если для любого из них IsDeleted установлено значение false, то объекты OrgDetails удовлетворяют требованиям и возвращаются. Если это НЕ то, что вы хотите, вам действительно нужно прояснить вопрос, чтобы мы могли предоставить точный ответ, основанный на точной информации.
Ответ №3:
Если я правильно понимаю ваш вопрос, вы пытаетесь: 1- Отфильтровать OrgDetails, для которых isRemove установлено значение false 2 — Для каждого элемента массива, полученного в 1 /, вы хотите отфильтровать членов организации и сохранить только те, которые не были удалены.
Вот как я бы это сделал:
var orgs = RealmManager.shared.read(condition: "isRemoved = false", object: OrgDetails.self)
orgs.forEach {
$0.orgMembers = Array($0.orgMembers.filter({ !$0.isDeleted }))
}
Комментарии:
1. @Ajay Хотя это может сработать, имейте в виду, что это отключает объекты от Realm, поэтому они больше не будут обновляться в реальном времени или наблюдаться. Кроме того, это приведет к потере аспекта ленивой загрузки объектов Realm, и если объектов много, это может привести к перегрузке памяти устройств. Кроме того, результаты фильтра не используются, поэтому не уверен, какой там план.
2. Спасибо за ответ. Я пробовал ваш код, но он выдает ошибку
Cannot assign value of type 'LazyFilterSequence<List<OrgMembers>>' to type 'List<OrgMembers>'