Ios 目标c-按单词搜索

Ios 目标c-按单词搜索,ios,objective-c,search,nspredicate,Ios,Objective C,Search,Nspredicate,我有一个图书应用程序,用户可以在其中浏览和搜索图书。 例如,以下是书籍列表: “腐肉舒适性” “遮住她的脸” “老人无乡” “猴子的雨衣” 我想实现一种搜索机制,其行为如下: 如果用户搜索“co”,结果将是: “腐肉舒适性” “遮住她的脸” “老无所依” 你可以注意到,我只想找到以“co”开头的单词,这就是为什么《猴子的雨衣》一书虽然包含“co”但没有出现在结果中的原因 为了实现这一点,我创建了一个名为Token的托管对象: Token ------ normalizedString

我有一个图书应用程序,用户可以在其中浏览和搜索图书。
例如,以下是书籍列表:

“腐肉舒适性”
“遮住她的脸”
“老人无乡”
“猴子的雨衣”

我想实现一种搜索机制,其行为如下:
如果用户搜索“co”,结果将是:

“腐肉舒适性”
“遮住她的脸”
“老无所依”

你可以注意到,我只想找到以“co”开头的单词,这就是为什么《猴子的雨衣》一书虽然包含“co”但没有出现在结果中的原因

为了实现这一点,我创建了一个名为
Token
的托管对象:

Token  
------
normalizedString  
我给我的书对象添加了一个多对多的关系

Book
-----
title  
releaseDate

tokens (to-many)  
现在我的搜索谓词是这样的:

[NSPredicate predicateWithFormat:@"SUBQUERY(tokens, $token, $token.normalizedString BEGINSWITH[cd] %@).@count > 0", [searchString lowercaseString]];  
如果我搜索单个单词,这很好,例如,如果我搜索“她”,我会得到结果:
“遮住她的脸”

但是当我尝试搜索多个单词时,例如“她的脸”,我没有得到任何结果

我理解为什么会发生这种情况,但在这里找不到正确的解决方案。

任何帮助都将不胜感激

我想这是一个黑客解决方案,但我会尝试以不同的方式生成代币。 令牌不是一个单词,而是从一个单词开始,并包含以下文本

因为“遮住她的脸”

而不是

Cover
Her
Face
我会尝试获得代币:

Cover Her Face
Her Face
Face

那么BEGINSWITH解决方案应该按照您的预期工作。这对您有意义吗?

假设您将书籍存储在
NSString*
s的
nsvariable数组中。。。(对不起,我不知道什么是
NSPredicate
。但是如果您能够将书籍转换为
NSString*
s,则可以使用此方法)

这可能不是最有效的方法,但它确实有效


除了提供每一种可能的变化之外,必须有一种方法来处理区分大小写的问题,但是我没有时间去弄清楚。可能在比较之前将所有内容都转换为小写?

为了回答我自己的问题,我最终标记了搜索字符串,并创建了一个更复杂的谓词来处理这些标记:

- (NSPredicate *)predicateForSearchString:(NSString *)searchString {    
    NSSet *searchTokens = [[Tokenizer sharedTokenizer] tokenize:searchString];

    NSMutableArray *subPreds = [NSMutableArray arrayWithCapacity:searchTokens.count];
    for (NSString *token in searchTokens) {
        NSPredicate *pred = [NSPredicate predicateWithFormat:@"SUBQUERY(tokens, $token, $token.normalizedString BEGINSWITH[cd] %@).@count > 0", token];
        [subPreds addObject:pred];
    }
    return [NSCompoundPredicate andPredicateWithSubpredicates:[subPreds copy]];
}

你显然想要的是一个KWIK索引。(查一查,应该有几种算法被提出。)在我看来,当你应该用两块石头的时候,你好像在试图用同一块石头打两只鸟。当u用户点击空格时,您不再需要检查前缀,而只需要检查包含?
- (NSPredicate *)predicateForSearchString:(NSString *)searchString {    
    NSSet *searchTokens = [[Tokenizer sharedTokenizer] tokenize:searchString];

    NSMutableArray *subPreds = [NSMutableArray arrayWithCapacity:searchTokens.count];
    for (NSString *token in searchTokens) {
        NSPredicate *pred = [NSPredicate predicateWithFormat:@"SUBQUERY(tokens, $token, $token.normalizedString BEGINSWITH[cd] %@).@count > 0", token];
        [subPreds addObject:pred];
    }
    return [NSCompoundPredicate andPredicateWithSubpredicates:[subPreds copy]];
}