Cloudkit 的 NSPredicate 匹配字符串

Posted

技术标签:

【中文标题】Cloudkit 的 NSPredicate 匹配字符串【英文标题】:NSPredicate matching string for Cloudkit 【发布时间】:2016-04-15 00:30:26 【问题描述】:

我需要从 cloudkit 中提取匹配字符串的记录。

我有一个用户记录类型,带有一个电子邮件字段。我有多个记录在同一个电子邮件中,但我无法获取谓词来获取记录。

我已经尝试了所有这些:

let predicate = NSPredicate(format: "email = 'julio_ukohgsp_chevez@tfbnw.net'")
NSPredicate(format: "email == %@", argumentArray: [email])
NSPredicate(format: "email IN %@", [email])
NSPredicate(format: "email contains %@", email)
NSPredicate(format: "email = %@", email)
NSPredicate(format: "email == %@", email)

我的查询指定了记录类型:

let query = CKQuery(recordType: "User", predicate: NSPredicate(format: "email == %@", email))

当我使用 value: true 进行谓词时,我会得到所有记录,包括我想要的记录。我确定我有一个用户使用该电子邮件,实际上是多个记录。

我错过了什么?

编辑..

let query = CKQuery(recordType: "User", predicate: NSPredicate(format: "email BEGINSWITH %@", email))

确实有效并带回了记录,但我想要一个完全匹配的!

【问题讨论】:

LIKE 代替 == 有效吗? 【参考方案1】:

我遇到了同样的问题,我可以通过在用户字段上添加可查询索引来解决它。请注意,添加索引后,我需要再次将数据写入 CloudKit 才能执行查询。

创建谓词的代码:

let user = "test-user"
let userPredicate = NSPredicate(format: "user == %@", user)

【讨论】:

使其可查询,这救了我.. 我不明白为什么我不能按谓词过滤,一旦我使我的属性可查询,我就可以用它来按特定的过滤云实体关系。我以为我在那里有一段时间无法建立很多关系。【参考方案2】:

我的一个应用也遇到了同样的问题。就我而言,我需要订阅一个谓词列表,其中需要满足许多搜索条件,但搜索或过滤谓词给我带来了最大的麻烦。我也试过了:

let word1 = "Mac"
    
let predicate = NSPredicate(format: "Title CONTAINS %@", word1)

这有效,但仅当“word1”是一个没有空格的单词并且“标题”是云中的“字符串列表”时。

我在所有研究中遇到的澄清是:

创建谓词时需要使用术语“self”,它会搜索所有可搜索字符串的字段。这是我从Apple's Website.得到的信息

谓词支持以下变量替换字符串:

将 %@ 用于字符串、数字和日期等值对象。

使用 %K 作为字段名称。此替换变量表示应使用替换的字符串来查找字段名称。

除了一个例外,CONTAINS 运算符只能用于测试列表成员资格。例外情况是当您使用它与自键路径一起执行全文搜索时。自键路径使服务器在可搜索的基于字符串的字段中查找指定的令牌字符串。例如,谓词字符串@"self contains 'blue'" 在所有标记为包含在全文搜索中的字段中搜索单词“blue”。您不能使用自键路径在类型不是字符串的字段中进行搜索。

我最终要做的,必须有更好的方法,是我的“标题”属性仍然是云中的“字符串列表”,在我的代码中,我在我的 searchTerm 和对于 searchTerm 中的每个单词,我制作了一个单独的 NSPredicate,并将它们用作 NSCompoundPredicate 的一部分。然后我将 NSCompoundPredicate 添加到我的订阅中,它起作用了。这是我的例子:

var searchCriteria: [NSPredicate] = []

for word in searchTerm 
    let predicate = NSPredicate(format: "self CONTAINS %@", word)
    searchCriteria.append(predicate)


let p2 = NSPredicate(format: "Price > %d", minPrice)

let p3 = NSPredicate(format: "Price < %d", maxPrice)

let p4 = NSPredicate(format: "Category == %d", category)

searchCriteria.append(p2)
searchCriteria.append(p3)
searchCriteria.append(p4)

let compoundPredicate = NSCompoundPredicate(andPredicateWithSubpredicates: searchCriteria)

我希望这会有所帮助。必须有更好的方法来做到这一点,如果有人知道,请告诉我,因为我知道关于如何使用 CloudKit 做事没有很多好的解释。

【讨论】:

你的评论很有趣,因为苹果回复我的雷达说问题已解决......但我无法测试它,因为我没有编码我的电子邮件并且没有从那以后就有问题了。 这很有趣。好吧,如果你最终测试它并且它对你有用,请告诉我你是如何做到的。

以上是关于Cloudkit 的 NSPredicate 匹配字符串的主要内容,如果未能解决你的问题,请参考以下文章

使用 NSPredicate 和数组进行 cloudKit 搜索

NSPredicate 使用 CloudKit 进行不区分大小写的字符串搜索

CloudKit,NSPredicate 在私有容器中返回计数或确定是不是存在任何记录?

CloudKit - NSPredicate 用于在引用列表中查找包含多个 CKReference 的所有记录

如何使用 NSPredicate 和 CloudKit 获取特定用户的最新帖子?

使用 NSPredicate 查询 CloudKit 以获取空白(或 null 或其他)的日期