Search code examples
searchfull-text-searchnspredicatecloudkit

How to do a CloudKit full text search that includes a token search


I am trying to create a CloudKit text search query. What does work is a query for the records that starts with the search text like this:

NSPredicate(format: "Text BEGINSWITH %@", searchText)! 

A token search also works (query to see if one of the entered words is somewhere in the record) like this:

NSPredicate(format: "allTokens TOKENMATCHES[cdl] %@", searchText)! 

You can see these queries working in the demo app off EVCloudKitDao (see screenshots)

But now I would like to combine these 2 queries so that the results feel a little more complete. I tried using this query:

NSPredicate(format: "Text BEGINSWITH %@ OR allTokens TOKENMATCHES[cdl] %@", searchText, searchText)! 

But then I will get this CloudKit error:

Terminating app due to uncaught exception 'CKException', reason: 'Unexpected expression: Text BEGINSWITH "Y" OR allTokens TOKENMATCHES[cdl] "Y"'

Besides that I also tried a NSCompoundPredicate like this:

    var p1 = NSPredicate(format: "allTokens TOKENMATCHES[cdl] %@", searchText)!
    var p2 = NSPredicate(format: "Text BEGINSWITH %@", searchText)!
    var p = NSCompoundPredicate(type: NSCompoundPredicateType.OrPredicateType, subpredicates: [p1, p2])

But that one gives about the same error:

Terminating app due to uncaught exception 'CKException', reason: 'Unexpected expression: allTokens TOKENMATCHES[cdl] "y" OR Text BEGINSWITH "y"'

The strange thing is that it does work when using the AndPredicateType instead of the OrPredicateType

Does anyone know an alternate solution for a query like this? Since it's for an autocomplete function, doing 2 queries and combining the results is not a real option.


Solution

  • Unfortunately, joins aren't supported in CloudKit queries. Your only option is to run two separate queries and combine the results of the two in your client.

    That's not very efficient, and we're aware of this limitation. If you have the time, a quick radar requesting this feature would be useful.

    Update: Per the documentation the only supported compound predicate operators are AND, &&, NOT. The OR operator is not supported in CloudKit. This isn't a bug- it is a known limitation of the server.