Tôi đang cố triển khai tìm kiếm trong ứng dụng của mình. Có hai thực thể Core Data, "Tag" và "DvarTorah". Thẻ chỉ có một chuỗi. "DvarTorah" có tiêu đề, nội dung văn bản và một số thuộc tính khác. Tôi đang cố gắng tìm ra cách tốt nhất để tìm kiếm chúng một cách nhanh chóng. Các ứng dụng tàu với khoảng 1200 thực thể DvarTorah, và thậm chí nhiều thẻ hơn. Ngay bây giờ, tôi tải lên một NSFetchedResultsController khi bộ điều khiển xem tìm kiếm của tôi gọi viewDidLoad. Sau đó, khi người dùng nhập vào hộp tìm kiếm hoặc thay đổi phạm vi, tôi gọi một phương thức nhận cả giá trị thanh phạm vi và cụm từ tìm kiếm và lọc mảng đối tượng của tôi. Dưới đây là cách hiển thị:Làm cách nào để tối ưu hóa tìm kiếm dựa trên Dữ liệu cốt lõi này?
- (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];
}
Vấn đề là phương pháp tìm kiếm của tôi rất chậm. Tôi biết rằng CONTAINS là một thủ phạm có khả năng, nhưng ngay cả sau khi lưu trữ một phiên bản chuẩn của nội dung (như searchableContent) và cố gắng tối ưu hóa hơn nữa, việc tìm kiếm là khủng khiếp chậm. Làm thế nào tôi có thể thực hiện điều này nhanh hơn?
Edit:
Dựa trên lời đề nghị ban đầu của Gia-cốp, đây là phương pháp mới của tôi:
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] mutableCopy] filteredArrayUsingPredicate:predicate]];
}
Edit2:
Không sao chép mảng nữa, vẫn còn chậm:
- (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]];
}
Có phải tất cả bốn phiên bản đều chậm? Các kết quả được đặt mà bạn đang lọc là bao nhiêu? Bạn có thể lấy đi bằng cách sử dụng một cái gì đó khác hơn là chứa? –
@ DavidRönnqvist - Tập kết quả là khoảng 1200 đối tượng. Có lẽ tôi hiểu lầm UISearchResultsController hoàn toàn ... Theo như chậm so sánh, tôi là profiling bằng mắt, không sử dụng một công cụ, vì vậy tôi không chắc chắn. Có vẻ như tôi cũng thế. – Moshe