Filtering count expression using existing subquery
In my app, I have a many-to-many relationship between tags and links as
follows :
Tags <<-->> Links
I am trying to return a list of the tags that relate to links that have
the currently active tags, but are not included in the active tags.
I also want to obtain a count of the number of links that have the 'other'
tags, which needs to be limited by the active tags.
Using the below, I have been able to return the 'other' tags and a count
of links, but the count returned is of all links for each tag.
I would like to be able to count the links using a similar approach to the
one I'm using to build the subquery, but am struggling to get it to work.
I have tried using the subquery generated in the count NSExpression, but
this errors when the subquery is evaluated.
// Test array of tag names
self.activeTagArray = [@[@"tag1", @"tag2"] mutableCopy];
NSFetchRequest *fetchRequest = [NSFetchRequest
fetchRequestWithEntityName:[Tag entityName]];
// We want to exclude the tags that are already active
NSPredicate *activeTagsPredicate = [NSPredicate predicateWithFormat:@"NOT
ANY name IN %@", self.activeTagArray];
// Build subquery string to identify links that have all of the active
tags in their tag set
NSString __block *subquery = @"SUBQUERY(links, $link, ";
[self.activeTagArray enumerateObjectsUsingBlock:^(id tagName, NSUInteger
index, BOOL *stop) {
if (index == self.activeTagArray.count - 1) {
subquery = [subquery stringByAppendingString:[NSString
stringWithFormat:@"SUBQUERY($link.tags, $tag, $tag.name = '%@') !=
NULL", tagName]];
} else {
subquery = [subquery stringByAppendingString:[NSString
stringWithFormat:@"SUBQUERY($link.tags, $tag, $tag.name = '%@') !=
NULL AND ", tagName]];
}
}];
subquery = [subquery stringByAppendingString:@") != NULL"];
NSLog(@"Subquery : %@", subquery);
NSPredicate *noTagsPredicate = [NSPredicate predicateWithFormat:subquery];
// Create a predicate array
NSArray *predicateArray = @[noTagsPredicate, activeTagsPredicate,
userPredicate];
NSPredicate *compoundPredicate = [NSCompoundPredicate
andPredicateWithSubpredicates:predicateArray];
fetchRequest.predicate = compoundPredicate;
fetchRequest.relationshipKeyPathsForPrefetching = @[@"links"];
// Set up the count expression
NSExpression *countExpression = [NSExpression expressionForFunction:
@"count:" arguments:@[[NSExpression expressionForKeyPath:
@"links.href"]]];
NSExpressionDescription *expressionDescription = [[NSExpressionDescription
alloc] init];
expressionDescription.name = @"counter";
expressionDescription.expression = countExpression;
expressionDescription.expressionResultType = NSInteger32AttributeType;
fetchRequest.propertiesToFetch = @[@"name", expressionDescription];
// Sort by the tag name
NSSortDescriptor *sortDescriptor = [NSSortDescriptor
sortDescriptorWithKey:@"name" ascending:YES];
fetchRequest.sortDescriptors = @[sortDescriptor];
fetchRequest.resultType = NSDictionaryResultType;
NSError *error = nil;
NSArray *resultsArray = [self.managedObjectContext
executeFetchRequest:fetchRequest error:&error];
if (error) {
NSLog(@"Error : %@", [error localizedDescription]);
}
NSMutableArray *allTags = [[NSMutableArray alloc] init];
for (NSDictionary *tagDict in resultsArray) {
NSLog(@"Tag name : %@, Link Count : %@", tagDict[@"name"],
tagDict[@"counter"]);
[allTags addObject:tagDict[@"name"]];
}
[allTags addObjectsFromArray:self.activeTagArray];
Any help with this would be greatly appreciated!
No comments:
Post a Comment