我正在尝试使用Swift中的Core Data键进行搜索。我希望得到相关的结果,无论是精确的还是接近的,按距离的顺序排序(从最接近的匹配到最远的匹配)。
例如,如果有人搜索“朋友”,我希望搜索结果类似于以下内容:“朋友”,“朋友”,“友好”和“朋友”。
我已经尽力实现这样的搜索,但我对这类代码还是比较陌生的,而我现在尝试的实现并不适合我。这是我的代码:
var request = NSFetchRequest(entityName: "db")
request.returnsObjectsAsFaults = false
request.predicate = NSPredicate(format: "dbKey MATCHES %@", ".*" + searchString + ".*")
var results: Array = context.executeFetchRequest(request, error: nil)!
if (results.count > 100) {
results.removeRange(Range(start: 100, end: results.count-1))
}
var sortedResults: Array = [results[0]]
for (var i = 1; i < results.count; ++i) {
if (countElements(results[i].valueForKey("dbKey") as String) < countElements(sortedResults[i-1].valueForKey("dbKey") as String)) {
var j = i-1
while (countElements(results[i].valueForKey("dbKey") as String) < countElements(sortedResults[j].valueForKey("dbKey") as String)) {
if (j != 0) {
--j
} else {
break
}
}
sortedResults.insert(results[i], atIndex: j)
} else {
sortedResults.append(results[i])
}
}
results = sortedResults
问题是双重的:
我试图找到一个可以包含我正在寻找的类型的搜索功能的库(类似Fuse.js),但我没有运气。任何帮助都将非常感激。
答案 0 :(得分:2)
您可以使用不同的谓词过滤结果,并决定使用哪个;
let result = NSPredicate(format: "dbKey CONTAINS[cd] %@", searchString)
let result = NSPredicate(format: "dbKey startsWith[cd] %@", searchString)
let result = NSPredicate(format: "dbKey LIKE '%@'", searchString)
对于特定订单,您应该使用 NSSortDescriptor
答案 1 :(得分:2)
不是您问题的实际答案,而是您正在尝试做的事情的解决方案:查看PermissiveResearch。
它看起来像这样:
extension UIViewController: PermissiveResearchDelegate {
// Call this once
func rebuildDatabase() {
PermissiveResearchDatabase.sharedDatabase().delegate = self
for db in allDbs { // Assuming allDbs is your array of DB objects
PermissiveResearchDatabase.sharedDatabase().addManagedObject(db, forKey: "dbKey")
}
}
// A basic search method
func search(searchString: String) {
PermissiveResearchDatabase.sharedDatabase().searchString(searchString, withOperation: ScoringOperationTypeExact)
}
// PermissiveResearchDelegate method
func searchCompletedWithResults(results: [AnyObject]!) {
let pResults = results as! [PermissiveCoreDataObject]
for result in pResults {
let db = try! self.managedObjectContext.existingObjectWithID(result.objectID) as! DB
print("\(result.score) - \(db.dbKey)")
}
}
}