如何编写NSPredicate来搜索多对多关系的日期属性?

时间:2019-01-26 05:51:12

标签: swift core-data predicate

我有一个“患者”对象,该对象与“行为”对象有很多关系(Patient.acts) Act对象的startDate属性类型为Date

我正在尝试编写NSPredicate,以使至少有一项行为的所有患者的startDate在今天开始

我正在使用Swift 4.2,使用的是XCode 10

我无法在以下位置找到正确的左表达式:

let start = NSExpression(forConstantValue: Calendar.current.startOfDay(for: Date()))
let end = NSExpression(forConstantValue: Calendar.current.endOfDay(for: Date()))
let todayRange = NSExpression(forAggregate: [start, end])
let actToday = NSComparisonPredicate(leftExpression: ????, rightExpression: todayRange, modifier: .any, type: .between, options: [])

对于leftExpression,我尝试了几种选择,但没有用:

let left = NSExpression(forConstantValue: "acts.startDate")

我尝试了一个子谓方法:

let actDate = NSPredicate(format: "$x.startDate")
let left = NSExpression(forSubquery: NSExpression(forKeyPath: "acts"), usingIteratorVariable: "x", predicate: actDate2)

更新并回答

我想出了以下表达式:

let seenToday = NSPredicate(format: "SUBQUERY(acts, $v, $v.actStartDate => %@ && $v.actStartDate < %@).@count!=0", argumentArray:[startToday, endToday] )

感谢vadian的回答。我现在想知道的问题是,按照vadian提出的方式执行此操作是否更有效,还是我的子查询谓词足够?

1 个答案:

答案 0 :(得分:0)

我建议获取给定日期的所有行为,并将它们映射到其患者属性(假设Act中存在适当的反向关系)

let interval = Calendar.current.dateInterval(of: .day, for: Date())!
let fetchRequest : NSFetchRequest<Act> = Act.fetchRequest()
fetchRequest.predicate = NSPredicate(format: "startDate BETWEEN %@", [interval.start, interval.end] as [CVarArg])

然后获取行为并将结果映射到一组患者

let acts = try context.fetch(fetchRequest)
let patients = Set(acts.map{$0.patient})