PFQuery с несколькими ограничениями на один ключ
У меня есть база данных parse.com. У меня есть столбец в таблице с именем "текст".
Я должен найти текст с несколькими ключами, соответствующими условию И.
Я пробовал все это. я попытался использовать:
PFQuery *query=[PFQuery queryWithClassName:@"post"];
[query whereKey:@"text" containedIn:Array];
или
PFQuery *query=[PFQuery queryWithClassName:@"post"];
[query whereKey:@"text" containsAllObjectsInArray:Array];
или
PFQuery *query=[PFQuery queryWithClassName:@"post"];
for (NSString *str in filtersArray) {
[query whereKey:@"text" containsString:str];
}
но никто не работает. пожалуйста, помогите мне, если parse sdks поддерживает это или не полностью? если да, то как я могу достичь результатов.
большое спасибо заранее:)
Eidt:
например, у меня есть три записи в базе данных в виде текста:
если передать "i" и "this", он должен вернуть запись (3)
если передать "i" и "data", он должен возвращать запись (1,2)
если передать "i" и "else", он ничего не должен возвращать
Ответы
Ответ 1
Причина, по которой ваш запрос не работает, заключается в том, что Parse не поддерживает одно и то же ограничение (в данном случае "containsString:" ) более одного раза на одном и том же ключе.
Итак, я бы предложил запросить регулярное выражение, которое будет соответствовать всем вашим строкам фильтра, используя - (instancetype)whereKey:(NSString *)key matchesRegex:(NSString *)regex
.
NSArray *qryStrings = @[str1, str2, str3, ....]; //strings you are trying to match
//string which will hold our regular expression
NSString *regexString = @"^"; //start off the regex
for (NSString *str in qryStrings) { //build the regex one filter at a time
regexString = [NSString stringWithFormat:@"%@(?=.*%@)", regexString, str];
}
regexString = [NSString stringWithFormat:@"%@.*$", regexString]; //finish off the regex
PFQuery *query = [PFQuery queryWithClassName:@"post"];
[query whereKey:@"text" matchesRegex:regexString];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
//objects array contains matching rows with matching strings
}
else {
NSLog(@"%@ %@", error, [error userInfo]);
}
}];
Ответ 2
В зависимости от требований к скорости вашего запроса и количества запрашиваемых объектов, я бы попытался выделить результаты с помощью componentsSeparatedByString:
после перечисления в массиве результатов, используя что-то вроде: for(NSString *string in results)
. После разделения каждой строки на отдельный массив используйте оператор if(...)
, который определяет, содержит ли эта коллекция слов каждое искомое слово.
Пример кода:
NSMutableArray *searchResults = [[NSMutableArray alloc] init];
PFQuery *query=[PFQuery queryWithClassName:@"post"];
// consider setting a limit, depending on the number of posts
// consider sorting the query as needed
NSArray *posts = [query findObjects];
for(NSString *text in posts)
{
NSArray *words = [text componentsSeparatedByString:@" "]; // use SeperatedByCharactersInSet: for . , or anything else you'd need
switch ([filterArray count])
{
case 1:
if([words containsObject:filterArray[0]])
{
[searchResults addObject:text];
}
break;
case 2:
if([words containsObject:filterArray[0]] &&
[words containsObject:filterArray[1]])
{
[searchResults addObject:text];
}
break;
// case n:
// if([words containsObject:filterArray[0]] &&
// [words containsObject:filterArray[1]] &&
// [words containsObject:filterArray[n]])
// {
// [searchResults addObject:text];
// }
//
// break;
default:
break;
}
_filteredResults = [NSArray arrayWithArray:searchResults]; // local global instance of results - use for maintaining order (be sure to clear it between searches)
Массив _filteredResults
должен быть тем, что вы хотите. Обязательно рассмотрите скорость и разделители символов, используемые в поиске.
Ответ 3
Вам просто нужно использовать whereKey:containsString:
И если вы хотите использовать дополнительные параметры, просто добавьте subQuery
Ответ 4
Ваше решение должно немного изменить.
Как это.
PFQuery *query=[PFQuery queryWithClassName:@"post"];
[query whereKey:@"text" containedIn:Array];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
//what your logic you want to write there might comes some records that are counts two times so you can remove those using NSSet
}];