我正在使用如下所示的Realm对象并创建了对象的数据库。我还创建了一个函数来根据当前时间查找元素。我在创建此函数所需的谓词时遇到困难。我正在使用Realm备忘单中定义的格式,但我得到如下例外:
由于未捕获的异常“无效的谓词”而终止应用,原因: '使用BETWEEN运算符的谓词必须将KeyPath与a进行比较 聚合有两个值'
import Foundation
import RealmSwift
func composeUniqueRealmPrimaryKeyForWorkorder(_ start:String) -> String {
return start
}
class WorkorderRecord: Object {
dynamic var id = ""
dynamic var workorder = ""
dynamic var start = "" // defines start time string as in 2017-06-09 9:00
dynamic var end = "" // defines end of interval as in 2017-06-10 16:30
override static func primaryKey() -> String? {
return "id"
}
override class func indexedProperties() -> [String] {
return ["workorder","start","end"]
}
convenience init(_ workorder:String, start:String, end:String) {
self.init()
self.id = composeUniqueRealmPrimaryKeyForWorkorder (workorder)
self.workorder = workorder
self.start = start
self.end = end
}
}
func getValueForInterval(time:String) -> String? {
let realm = try! Realm()
let predicate = NSPredicate(format: "%@ BETWEEN {start , end }", time)
let r = realm.objects(WorkorderRecord.self).filter(predicate)
if r.count == 0 {
print("NO RECORD FOUND")
return ""
} else {
let workorder = r[0].workorder
let start = r[0].start
let end = r[0].end
print("RECORD Retrieved: workorder= \(workorder) start= \(start) end= \(end)")
return workorder
}
}
答案 0 :(得分:2)
如果您推断BETWEEN
运算符提供的语义,您很快就会发现foo BETWEEN {bar, baz}
等同于foo >= bar AND foo <= baz
[0]。虽然Realm目前仅支持{bar, baz}
聚合表达式中的常量值,但对正常的关系比较运算符没有这样的限制。
您将遇到的一个问题是,虽然Realm支持数字和>=
类型的<=
和Date
等比较运算符,但字符串类型目前不支持它们。由于您将开始和结束时间存储为字符串,因此无法在不进行进一步更改的情况下利用此转换。
如果您使用Date
类型切换到存储时间,则可以将查询重新表述为:
let predicate = NSPredicate(format: "%@ >= start AND %@ <= end", time, time)
这样做还可以减少存储日期所需的空间。
[0]:请注意,仅当密钥路径foo
不遍历任何多对多关系时才会出现这种情况。如果它确实遍历多个关系,则需要SUBQUERY
来匹配BETWEEN
的语义。