2013-08-09 2 views
9

Я пишу приложение, имеющее базу данных фотографий. Каждая фотография имеет несколько тегов, связанных с ней, и приложение имеет страницу поиска с множеством переключателей, которая позволяет пользователям искать фотографии на основе только те теги, которые представляют для них интерес. Каждый из этих тегов хранит integer ID, потому что они соответствуют идентификаторам внешней базы данных, поэтому я пытаюсь найти их просто по ID. Все поля идентификатора индексируются.iOS Compound Predicates

Проблема возникает, когда предикаты, которые я пишу, становятся довольно большими, потому что пользователь может выбирать из множества разных тегов для фильтрации. Эти теги сгруппированы в 3 категории [публикации, бренды & продуктов], и поэтому мои запросы настроены как «OR» в категории и «AND» по этим категориям.

Пример предикат запрос заканчивает тем, что-то вроде этого:

(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) 

Они могут получить гораздо больше, но вы получите точку. Моя проблема заключается в том, что все эти выполняют дорогостоящие соединения, как только пользователь выбирает более 10 или 15, запросы выполняются очень долго и даже могут привести к сбою приложения.

Похоже, что это было бы более эффективным, чтобы написать что-то вроде:

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)) 

Но я не могу получить, что синтаксис для работы.

Так что мой вопрос: поддерживается ли этот тип синтаксиса, и если да, может кто-нибудь покажет мне, как правильно его написать?

Или есть лучший способ приблизиться к этим типам запросов в отношении основных данных?

ответ

16

Использование коллекции предикаты, как

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

Теперь вы просто должны держать три массива атрибутов и сделать трехстороннюю соединение предиката с andPredicateWithSubpredicates.

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

Должно выполняться ОК.

+0

Благодаря @Mundi, но всякий раз, когда я пытаюсь использовать этот синтаксис он дает мне ошибку: Не удается разобрать строку формата «ANY brands.brandId IN ( 12, 0, 1 )»» –

+0

Пожалуйста, попробуйте ВСЕ. Если это сработает, я поправлю свой ответ. – Mundi

+0

Тот же результат: «NSInvalidArgumentException», причина: «Невозможно разобрать строку формата» ВСЕ бренды.brandId IN ( 12, 0,) ". Кажется, что структура массива, передаваемая в предложение «IN», недопустима или неправильно отформатирована. –