2011-12-05 4 views
0

NSPredicate을 사용하여 NSManagedObject 인스턴스의 배열을 검색하고 있습니다. 각 "기사"는 "제목", "내용"을 가지며 잠재적으로 여러 "태그"와 일치합니다.이 NSPredicate를 최적화 하시겠습니까?

기사의 내용과 일치시키는 정규식을 사용하고 싶습니다. 다른 검색 연산자는 다른 모든 항목에 적합합니다. 문제는 내 검색이 아주 천천히 진행된다는 것입니다. 다음은 내가 가지고있는 것입니다.

- (void) filterArrayWithSearchTerm:(NSString *)searchString andScopeIndex:(NSInteger)scopeIndex{ 

// 
// Grab a local copy of the search string. 
// This is done simply for convenience in the 
// following set of if statements. 
// 

NSMutableString *modifiedSearchString = [searchString mutableCopy]; 
NSPredicate *predicate; 

//1 is "content" and 3 is "all" 
if(scopeIndex == 1 || scopeIndex == 3){ 

    NSInteger length = [searchString length]; 

    NSString *vowelsAsRegex = @"[\u0591-\u05c4]?[\u0591-\u05c4]?"; 

    //If our search includes the body of the text 

    for (int i = length; i > 0; i--) { 
     [modifiedSearchString insertString:vowelsAsRegex atIndex:i]; 
    } 

    [modifiedSearchString insertString:@".*" atIndex:0]; 
    [modifiedSearchString appendString:@".*"]; 
} 

// 
// Depending on the selected scope bar option 
// we perform a "MATCHES" search. 
// 
// For searching properties of related entities, we use the ANY keyword 
// 

//NSLog(@"Regex: %@", modifiedSearchString); 

if (scopeIndex == 0) { 
    predicate = [NSPredicate predicateWithFormat:@"articleTitle CONTAINS[cd] %@", modifiedSearchString]; 
}else if (scopeIndex == 1) { 
    predicate = [NSPredicate predicateWithFormat:@"articleContent CONTAINS[cd] %@", modifiedSearchString];    
}else if (scopeIndex == 2){ 
    predicate = [NSPredicate predicateWithFormat:@"ANY tags.tagText MATCHES[cd] %@", modifiedSearchString]; 
}else{ 
    predicate = [NSPredicate predicateWithFormat:@"(ANY tags.tagText CONTAINS[cd] %@) OR (articleTitle CONTAINS[cd] %@) OR (articleContent MATCHES[cd] %@)", modifiedSearchString, modifiedSearchString, modifiedSearchString]; 
} 

[modifiedSearchString release]; 

NSMutableArray *unfilteredResults = [[[[self.fetchedResultsController sections] objectAtIndex:0] objects] mutableCopy]; 

// 
// Ensure that we have an array to work with. 
// 

if (self.filteredArray == nil) { 
    self.filteredArray = [[[NSMutableArray alloc ] init] autorelease]; 
} 

// 
// Clear out any existing objects from earlier. 
// 

[filteredArray removeAllObjects]; 


// 
// Perform the filtering by looping 
// through the articles and checking 
// it against the predicate. 
// 

for (Article *article in unfilteredResults) { 

    if ([predicate evaluateWithObject:article]) 
     [self.filteredArray addObject:article]; 

} 
// 
// Release the unfiltered array. 
// 

[unfilteredResults release]; 
} 

검색 속도를 높이기 위해 어떤 최적화를 적용 할 수 있습니까?

편집 : 별도의 배열을 주석을 제거, 조금 내 코드를 제거했습니다

. 나는 특별히 NSPredicate를 "contains"와 "match"를 최적화하는 방법에 대해 묻습니다. 여기에 새로운 코드가있다 :

- (void) filterArrayWithSearchTerm:(NSString *)searchString andScopeIndex:(NSInteger)scopeIndex{ 


NSMutableString *modifiedSearchString = [searchString mutableCopy]; 
NSPredicate *predicate; 

if(scopeIndex == 1 || scopeIndex == 3){ 

    NSInteger length = [searchString length]; 

    NSString *vowelsAsRegex = @"[\u0591-\u05c4]?[\u0591-\u05c4]?"; //Trop: \u0591-\u05AF Nekudot: \u05b0-\u05c 

    for (int i = length; i > 0; i--) { 
     [modifiedSearchString insertString:vowelsAsRegex atIndex:i]; 
    } 

    [modifiedSearchString insertString:@".*" atIndex:0]; 
    [modifiedSearchString appendString:@".*"]; 
} 

if (scopeIndex == 0) { 
    predicate = [NSPredicate predicateWithFormat:@"articleTitle CONTAINS[cd] %@", modifiedSearchString]; 
}else if (scopeIndex == 1) { 
    predicate = [NSPredicate predicateWithFormat:@"articleContent CONTAINS[cd] %@", modifiedSearchString];    
}else if (scopeIndex == 2){ 
    predicate = [NSPredicate predicateWithFormat:@"ANY tags.tagText MATCHES[cd] %@", modifiedSearchString]; 
}else{ 
    predicate = [NSPredicate predicateWithFormat:@"(ANY tags.tagText CONTAINS[c] %@) OR (articleTitle CONTAINS[c] %@) OR (articleContent MATCHES[cd] %@)", modifiedSearchString, modifiedSearchString, modifiedSearchString]; 
} 

[modifiedSearchString release]; 

NSMutableArray *unfilteredResults = [[[[self.fetchedResultsController sections] objectAtIndex:0] objects] mutableCopy]; 

[unfilteredResults filterUsingPredicate:predicate]; 
self.filteredArray = unfilteredResults; 

[unfilteredResults release]; 
} 

답변

0

이 줄 :

NSString *vowelsAsRegex = @"[\u0591-\u05c4]?[\u0591-\u05c4]?"; 

가 동일해야이 하나

정규식 매칭에 지점의 수를 감소한다고
NSString *vowelsAsRegex = @"[\u0591-\u05c4]{0,2}"; 

하지만, tbh, 나도 몰라.

+0

이 방법이 가장 좋은 해결책 일 수 있지만, 정규식을 넘어선 추가 최적화가 필요합니다. – Moshe

1

첨부;

NSMutableString *modifiedSearchString = [[NSMutableString alloc] init]; 

if(scopeIndex == 1 || scopeIndex == 3) 
{ 

    NSString *vowelsAsRegex = @"[\u0591-\u05c4]?[\u0591-\u05c4]?"; 

    [modifiedSearchString appendString:@".*"]; 

    for (int i = 0, length = [searchString length]; i < l; i++) 
    { 
     [modifiedSearchString appendString:vowelsAsRegex]; 
     [modifiedSearchString appendString:[searchString characterAtIndex:i]]; 
    } 

    [modifiedSearchString appendString:@".*"]; 
} 
관련 문제