Is there a way to limit the maximum number of file search results that are returned from an NSMetadataQuery
query on macOS? Currently, if I enter 1-2 characters as a query string, it takes over 5 seconds to receive the initial set of results, and the result count is about 100k-300k, while I only need the top 50 results. The query time reduces down to a few milliseconds if my query string is 5 characters long.
I tried the same with MDQuery
and was able to limit the max. results to 50 using MDQuerySetMaxCount
, so I was wondering if there was something similar in NSMetadataQuery
? I've seen Alfred and similar apps return the top 20-40 results almost instantly with every keystroke.
Here's what I have so far:
class MDQSearch {
var metadataQuery = NSMetadataQuery()
init() {
registerNotifications()
metadataQuery.searchScopes = [NSString("~/Documents").expandingTildeInPath]
}
func updateQuery(to queryString: String) {
guard queryString.count > 0 else { return }
metadataQuery.predicate = NSPredicate(format: "%K CONTAINS[cd] %@", argumentArray: [NSMetadataItemFSNameKey, queryString])
metadataQuery.start()
}
func registerNotifications() {
NotificationCenter.default.addObserver(self, selector: #selector(onQueryDidFinishGathering), name: NSNotification.Name.NSMetadataQueryDidFinishGathering, object: metadataQuery)
NotificationCenter.default.addObserver(self, selector: #selector(onQueryGatheringProgress), name: NSNotification.Name.NSMetadataQueryGatheringProgress, object: metadataQuery)
NotificationCenter.default.addObserver(self, selector: #selector(onQueryDidUpdate), name: NSNotification.Name.NSMetadataQueryDidUpdate, object: metadataQuery)
}
@objc func onQueryDidUpdate() {
print("QueryDidUpdate")
}
@objc func onQueryDidFinishGathering() {
print("QueryDidFinishGathering")
metadataQuery.stop()
print("result count: \(metadataQuery.resultCount)")
}
@objc func onQueryGatheringProgress() {
print("QueryGatheringProgress")
if(metadataQuery.resultCount >= 50) {
metadataQuery.stop()
print("result count: \(metadataQuery.resultCount)")
}
}
}
CodePudding user response:
I would suggest that the problem is your use of NSMetadataItemFSNameKey
. That's slow because the file system must be consulted. Use the display name key instead; that's information indexed by Spotlight, so it's fast.