2013-08-09 12 views
9

Piszę aplikację, która ma bazę danych zdjęć. Każde zdjęcie ma przypisane kilka tagów, a aplikacja ma stronę wyszukiwania z wieloma przełącznikami, która pozwala użytkownikom wyszukiwać zdjęcia na podstawie tylko tych tagów, które są dla nich interesujące. Każdy z tych tagów zapisał identyfikatory integer, ponieważ odpowiadają one identyfikatorom zewnętrznej bazy danych, więc staram się je wyszukać po prostu przez ID. Wszystkie pola ID są indeksowane.Komponent iOS Predykaty

Problem pojawia się, gdy predykaty, które piszę, stają się dość duże, ponieważ użytkownik może wybierać spośród wielu różnych tagów do filtrowania. Tagi te są pogrupowane w 3 kategorie [publikacje, produkty marek &], więc moje zapytania zostały skonfigurowane tak, aby były "OR" w ramach kategorii i "AND" w tych kategoriach.

Przykładem predykat kwerendy kończy się szuka czegoś takiego:

(parentPublication.publicationId==1 OR parentPublication.publicationId==2 OR parentPublication.publicationId==5) 
AND (ANY brands.brandId==12 OR ANY brands.brandId==2 OR ANY brands.brandId==0 OR ANY brands.brandId==3 OR ANY brands.brandId==5 OR ANY brands.brandId==6 OR ANY brands.brandId==7) 
AND (ANY products.productId==2 OR ANY products.productId==3 OR ANY products.productId==6) 

mogą uzyskać znacznie większe, ale masz rację. Mój problem polega na tym, że wszystkie z nich są wykonujące drogie połączenia, gdy użytkownik wybierze więcej niż 10 lub 15, zapytania będą działać wyjątkowo długo, a nawet powodować awarię aplikacji.

Wydaje się, że byłoby bardziej efektywne, aby napisać coś takiego:

parentPublication.publicationId IN (1,2,5) 
AND (ANY brands.brandId IN (12,2,0,3,5,6,7)) 
AND (ANY products.productId IN (2,3,6)) 

Ale nie mogę wydawać się stać, że składnia do pracy.

Moje pytanie brzmi: czy ten typ składni jest obsługiwany, a jeśli tak, czy ktoś może mi pokazać, jak poprawnie go napisać?

A może istnieje lepszy sposób podejścia do tego typu zapytań względem danych podstawowych razem?

Odpowiedz

16

predykaty Zastosowanie zbiórki, jak

[NSPredicate predicateWithFormat:@"parentPublication.publicationID in %@", pubIDs]; 
[NSPredicate predicateWithFormat:@"brands.brandID in %@", brandIDs]; 
[NSPredicate predicateWithFormat:@"product.productID in %@", productIDs]; 

Teraz po prostu trzeba zachować trzy tablice atrybutów i dokonać trójdrożny związek orzecznik z andPredicateWithSubpredicates.

[NSCompoundPredicate andPredicateWithSubPredicates:@[ 
    pubPredicate, brandPredicate, productPredicate]]; 

Należy wykonać OK.

+0

Dzięki @Mundi, ale gdy próbuję użyć tej składni to wyskakuje mi błąd: Nie można przetworzyć ciąg formatu „każdy brands.brandId IN (0,)”” –

+0

Spróbuj z WSZYSTKO. Jeśli to zadziała, zmienię moją odpowiedź. – Mundi

+0

Ten sam wynik: 'NSInvalidArgumentException', powód: "Nie można przeanalizować łańcucha formatu" ALL brands.brandId IN ( 12, 0,) "". Wygląda na to, że struktura tablicowa przekazywana do klauzuli "IN" jest niedozwolona lub niewłaściwie sformatowana. –