使用NSPredicate搜索多个字段

时间:2015-03-13 22:40:37

标签: realm

我有一个UITableView,希望能够使用 NSPredicate RMLResults 数组中的每个 RMLObject 条目中) >。我试图通过使用' OR '来做到这一点。在predicateFormatString中:

NSString *predicateFormat = @"(transactionDescription CONTAINS [c] %@) OR (transactionNote CONTAINS [c] %@)";

NSPredicate *predicate = [NSPredicate predicateWithFormat:predicateFormat, searchText, searchText];

searchText 是一个NSString, transactionDescription TransactionNote 是RLMObject中的NSString属性。

我将谓词传递给以下REALM API调用:

- (RLMResults *)objectsWithPredicate:(NSPredicate *)predicate;

但是,这并没有找到searchText属于该属性的所有字段或记录。

如果我将其限制为单个字段( transactionDescription ),它会找到所有实例:

predicateFormat = @"transactionDescription CONTAINS [c] %@";

编辑:以下是我现在拥有的内容(并且仍未找到包含匹配项的所有对象):

RLMResults *dataToSearch =  < code to fill dataToSearch here ... >;

// show dataToSearch

NSLog(@"dataToSearch:  %@", [dataToSearch description]);

// build predicate

NSString *predicateFormat = @"(transactionDescription CONTAINS [c] %@) OR (transactionNote CONTAINS [c] %@)";
NSPredicate *predicate = [NSPredicate predicateWithFormat:predicateFormat, searchText, searchText];

// search

_searchResults  = [dataToSearch objectsWithPredicate:predicate];

// show results

NSLog(@"searchResults:  %@",[_searchResults description]);

实际数据有5个实例,其中一个或另一个字段具有&#34; g&#34;在字符串中。他们是:

  • transactionDescription:4
  • transactionNote:1

我尝试了3种不同的NSPredicate格式:

// A:

NSString *predicateFormat = @"(transactionDescription CONTAINS [c] %@) OR (transactionNote CONTAINS [c] %@)";
NSPredicate *predicate = [NSPredicate predicateWithFormat:predicateFormat, searchText, searchText];

// B:

NSString *predicateFormat = @"(transactionDescription CONTAINS [c] %@)";
NSPredicate *predicate = [NSPredicate predicateWithFormat:predicateFormat, searchText];

// C:

NSString *predicateFormat = @"(transactionNote CONTAINS [c] %@)";
NSPredicate *predicate = [NSPredicate predicateWithFormat:predicateFormat, searchText];

(复合)谓词A发现:

  • transactionDescription中的1个实例
  • transactionNote中的1个实例

Predicate B发现:

  • transactionDescription
  • 中的4个(所有)实例
  • transactionNote中的0个实例

发现谓词C:

  • transactionDescription中的0个实例
  • 在transactionNote中唯一的实例

谓词格式B&amp; C似乎按预期运行 - 它们只搜索单个字段,并查找字符串具有字符的所有实例&#39; g&#39;在它。

虽然谓词A(复合谓词)似乎确实在查看这两个字段,但在找到2次点击(缺少其他3个)之后似乎停止了搜索。

我在几个配置中尝试了ANY聚合运算符,但是在调用objectsWithPredicate时,所有以下NSPredicates(以及其他几个变体)都会导致异常:

@"ANY (transactionDescription CONTAINS [c] %@) OR ANY transactionNote CONTAINS [c] %@)";

@"(ANY transactionDescription CONTAINS [c] %@) OR (ANY transactionNote CONTAINS [c] %@)";

@"ANY (transactionDescription CONTAINS [c] %@ OR transactionNote CONTAINS [c] %@)";

为什么(复合)Predicate A在找到2次命中后会发现哪些线索?

1 个答案:

答案 0 :(得分:3)

来自Realm的乔在这里。这是正确的方法。你能分享更多的代码和可能的样本数据吗?我只是尝试在我的机器上复制它,它没有任何问题。

例如,我使用随机名称和电子邮件保存了几个用户,然后使用此谓词来搜索它们。它正确地过滤了结果。

@interface User : RLMObject
@property NSString *name;
@property NSString *email;
@end

@implementation User

@end

- (void)viewDidLoad {
    [super viewDidLoad];

    RLMRealm *realm = [RLMRealm defaultRealm];
    [realm transactionWithBlock:^{
      [realm addObject:[User createInRealm:realm withObject:@[@"Jake", @"gmail"]]];
      [realm addObject:[User createInRealm:realm withObject:@[@"Jess", @"hotmail"]]];
      [realm addObject:[User createInRealm:realm withObject:@[@"May", @"gmail"]]];
    }];
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"email CONTAINS[c] %@ OR name CONTAINS[c] %@", @"gmail", @"b"];
    RLMResults *fetchedUsers = [User objectsWithPredicate:predicate];
    NSLog(@"%@", fetchedUsers);
}

编辑:下面的评论想知道如何搜索多个字段

let searchString = "John"
let subpredicates = ["name", "firstName", "lastName"].map { property in
    return NSPredicate(format: "%K CONTAINS %@", property, searchString)
}
let predicate = NSCompoundPredicate(orPredicateWithSubpredicates: subpredicates)
let johns = realm.objects(Person).filter(predicate)