私は自分のアプリで検索を実装しようとしています。コアデータエンティティには、「タグ」と「DvarTorah」の2つがあります。タグは単なる文字列です。 「DvarTorah」にはタイトル、テキストコンテンツ、その他のプロパティがあります。私はそれらをすばやく検索する最良の方法を見つけようとしています。約1200のDvarTorahエンティティ、さらに多くのタグが付属しています。現在、検索ビューコントローラがviewDidLoadを呼び出すと、NSFetchedResultsControllerがロードされます。ユーザーが検索ボックスに入力するかスコープを変更すると、スコープバーの値と検索タームの両方を取得し、オブジェクトの配列をフィルタリングするメソッドを呼び出します。その外観は次のとおりです。このコアデータベースの検索を最適化するにはどうすればよいですか?
- (void) filterArrayWithSearchTerm:(NSString *)searchString andScopeIndex:(NSInteger)scopeIndex{
if ([searchString isEqualToString:@""]) {
return;
}
NSMutableArray *unfilteredResults = [[[[self.fetchedResultsController sections] objectAtIndex:0] objects] mutableCopy];
if (self.filteredArray == nil){
self.filteredArray = [[[NSMutableArray alloc ] init] autorelease];
}
[filteredArray removeAllObjects];
NSPredicate *predicate = [[[NSPredicate alloc] init] autorelease];
if (scopeIndex == 0) {
predicate = [NSPredicate predicateWithFormat:@"dvarTorahTitle CONTAINS[cd] %@", searchString];
}else if (scopeIndex == 1) {
predicate = [NSPredicate predicateWithFormat:@"searchableContent CONTAINS[cd] %@", [searchString canonicalString]];
}else if (scopeIndex == 2){
predicate = [NSPredicate predicateWithFormat:@"ANY tags.tagText CONTAINS[cd] %@", searchString];
}else{
predicate = [NSPredicate predicateWithFormat:@"(ANY tags.tagText CONTAINS[cd] %@) OR (dvarTorahTitle CONTAINS[cd] %@) OR (searchableContent CONTAINS[cd] %@)", searchString,searchString,searchString];
}
for (DvarTorah *dvarTorah in unfilteredResults) {
if ([predicate evaluateWithObject:dvarTorah]) {
[self.filteredArray addObject:dvarTorah];
}
}
[unfilteredResults release];
}
問題は私の検索方法がひどく遅いことです。私はCONTAINSが起こりそうな原因だと知っていますが、コンテンツの標準バージョン(searchableContent)を保存してさらに最適化しようとしても、検索は恐ろしく遅いです。これをもっと速くするにはどうすればいいですか?
編集:
EDIT2:ヤコブの最初の提案に基づいて
は、ここに私の新しい方法です
まだ遅い、もはや配列をコピーしない:
- (void) filterArrayWithSearchTerm:(NSString *)searchString andScopeIndex:(NSInteger)scopeIndex{
if ([searchString isEqualToString:@""]) {
return;
}
if (self.filteredArray == nil) {
self.filteredArray = [[[NSMutableArray alloc ] init] autorelease];
}
[filteredArray removeAllObjects];
NSPredicate *predicate = nil;
if (scopeIndex == 0) {
predicate = [NSPredicate predicateWithFormat:@"dvarTorahTitle CONTAINS[cd] %@", searchString];
}else if (scopeIndex == 1) {
predicate = [NSPredicate predicateWithFormat:@"searchableContent CONTAINS[cd] %@", [searchString canonicalString]];
}else if (scopeIndex == 2){
predicate = [NSPredicate predicateWithFormat:@"ANY tags.tagText CONTAINS[cd] %@", searchString];
}else{
predicate = [NSPredicate predicateWithFormat:@"(ANY tags.tagText CONTAINS[cd] %@) OR (dvarTorahTitle CONTAINS[cd] %@) OR (searchableContent CONTAINS[cd] %@)", searchString,searchString,searchString];
}
[self.filteredArray addObjectsFromArray:[[[[self.fetchedResultsController sections] objectAtIndex:0] objects] filteredArrayUsingPredicate:predicate]];
}
すべて平等に遅い4つのバージョンはありますか?あなたがフィルタリングしている結果セットの大きさはどれくらいですか?あなたは含まれているもの以外のものを使うことで逃げることができますか? –
@DavidRönnqvist - 結果セットは約1200のオブジェクトです。おそらく私はUISearchResultsControllerを誤解しています...比較の遅さに関しては、私は目でプロファイリングしていますが、ツールを使用していないので、わかりません。私と同じように思える。 – Moshe