Xcode:使用复杂谓词过滤核心数据集

Posted

技术标签:

【中文标题】Xcode:使用复杂谓词过滤核心数据集【英文标题】:Xcode: Using a complex predicate to filter a core data set 【发布时间】:2012-02-09 01:01:12 【问题描述】:

编辑:我正在添加一个新的粗糙表模型以供评论。这是你的想法吗?

我仍在尝试为核心数据集制定搜索过滤器。我被卡住了here,所以我以不同的方式解决问题。

首先,我要做的是:

    遍历所有对象(NSManageObject *object in tableViewModel.items)

    提取每个“对象”的所有子实体对象并根据搜索词进行验证。

    如果子实体中确实存在搜索词,则将“object”添加到“autoSearchResults”(如果它不存在)

我的代码如下:

NSLog(@"%s", __FUNCTION__);

    NSMutableArray *startArray = [NSMutableArray array];
    NSMutableArray *filteredArray = [NSMutableArray array];

    for (NSManagedObject *object in tableViewModel.items) 
    
        NSLog(@"1 ");

        NSSet *set1 = [object valueForKeyPath:@"people.name"];
        NSString *str1 = [[set1 allObjects] componentsJoinedByString:@", "];
        peopleSet = str1;

        NSLog (@"peopleSet is %@ ", peopleSet);

        NSLog(@"2 ");
        NSSet *set2 = [object valueForKeyPath:@"place.name"];
        NSString *str2 = [[set2 allObjects] componentsJoinedByString:@", "];        
        placeSet = str2;

        NSLog(@"3 ");
        NSSet *set3 = [object valueForKeyPath:@"keyword.name"];
        NSString *str3 = [[set3 allObjects] componentsJoinedByString:@", "];        
        keywordSet = str3;

        NSLog(@"4 ");
        NSSet *set4 = [object valueForKeyPath:@"type.name"];
        NSString *str4 = [[set4 allObjects] componentsJoinedByString:@", "];        
        typeSet = str4;     

        NSLog(@"5 ");
        NSSet *set5 = [object valueForKeyPath:@"symbol.name"];
        NSString *str5 = [[set5 allObjects] componentsJoinedByString:@", "];        
        symbolSet = str5;

        NSLog(@"6 ");

        NSLog (@"searchText is: %@ ", searchText);

        myPredicate = [NSPredicate predicateWithFormat:@"(peopleSet contains[cd] %@) || (placeSet contains[cd] %@) || (keywordSet contains[cd] %@) || (typeSet contains[cd] %@) || (symbolSet contains[cd] %@)", searchText, searchText, searchText, searchText, searchText ];

        NSLog(@"7 ");       
        if (myPredicate) 
            [startArray addObject:object];
            NSLog (@"startArray.count is %i ", startArray.count);
        

        NSLog(@"8 ");
        NSLog (@"startArray.count is %i ", startArray.count);
        /*
        if (startArray.count == 0)
        
            NSLog(@"0");
         else             
            NSLog(@"9 ");
            [filteredArray addObject: startArray];
            NSLog(@"10 ");
            [startArray removeAllObjects];
            NSLog(@"11 ");
        
        */

           


    //autoSearchResults = filteredArray;
    return autoSearchResults;

在我的测试中,我有 3 个对象,一个是 person.name “me”,一个是“you”,一个是“Mother”。所有对象中的所有其他字段均为空白。

现在,我停下来看看每次搜索选择了多少对象。本质上,searchText 被找到但被忽略了。也就是说,例程看到 searchText 包含例如“我”,但仍然添加了一个对象,其中实际文本是“你”。

如果有任何帮助,我将不胜感激。如果有助于减少这个例子,请告诉我。

【问题讨论】:

【参考方案1】:

这段代码最严重的错误是您实际上并没有使用您创建的谓词。为了根据谓词测试对象,请在谓词上调用evaluateWithObject:,传入要测试的对象。

但这仍然行不通,因为它不知道“peopleSet”和所有其他字符串是什么:您不能像使用键路径一样使用局部变量。

最后,这个结构并没有真正利用谓词的力量;您正在使用像正则表达式这样的谓词。要实际过滤对象集合,请在集合本身上使用诸如filteredSetUsingPredicate: 之类的方法,而不是测试每个对象。

当然,这将要求您在托管对象模型上创建一个临时属性来存储串联的名称列表,但如果您正确执行此操作,执行此类过滤时您会看到性能提升。

【讨论】:

以上是关于Xcode:使用复杂谓词过滤核心数据集的主要内容,如果未能解决你的问题,请参考以下文章

使用基于属性的过滤子元素集获取核心数据实体

谓词下推

使用谓词过滤 pyarrow.parquet.ParquetDataset 中的行

xCode / iOS - 需要帮助使核心数据搜索谓词工作

核心数据中的谓词和组合过滤器?

核心数据谓词根据日期属性过滤对象