objective c - Filtering many-to-many count expression using existing subquery -


in app, have many-to-many relationship between tags , links follows :

tags <<-->> links 

i trying return list of tags relate links have active tags, not included in active tags.

i want obtain count of number of links have 'other' tags, needs limited active tags.

using below, have been able return 'other' tags , count of links, count returned of links each tag.

i able count links using similar approach 1 i'm using build subquery, struggling work. have tried using subquery generated in count nsexpression, errors when subquery evaluated.

// test array of tag names self.activetagarray = [@[@"tag1", @"tag2"] mutablecopy];  nsfetchrequest *fetchrequest = [nsfetchrequest fetchrequestwithentityname:[tag entityname]];  // want exclude tags active nspredicate *activetagspredicate = [nspredicate predicatewithformat:@"not name in %@", self.activetagarray];  // build subquery string identify links have of active tags in 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 , ", tagname]];     } }];  subquery = [subquery stringbyappendingstring:@") != null"];  nslog(@"subquery : %@", subquery);  nspredicate *notagspredicate = [nspredicate predicatewithformat:subquery];   // create predicate array nsarray *predicatearray = @[notagspredicate, activetagspredicate, userpredicate]; nspredicate *compoundpredicate = [nscompoundpredicate andpredicatewithsubpredicates:predicatearray];  fetchrequest.predicate = compoundpredicate; fetchrequest.relationshipkeypathsforprefetching = @[@"links"];  // set 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 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]; (nsdictionary *tagdict in resultsarray) {     nslog(@"tag name : %@, link count : %@", tagdict[@"name"], tagdict[@"counter"]);     [alltags addobject:tagdict[@"name"]]; }  [alltags addobjectsfromarray:self.activetagarray]; 

any appreciated!

if understand question correctly, following predicate fetches "other tags", i.e. tags related link related of given "active tags":

nsarray *activetags = @[@"tag1", @"tag2"];  nsfetchrequest *request = [nsfetchrequest fetchrequestwithentityname:@"tag"];  nspredicate *p1 = [nspredicate predicatewithformat:@"not name in %@", activetags]; nspredicate *p2 = [nspredicate predicatewithformat:@"subquery(links, $l, subquery($l.tags, $t, $t.name in %@).@count = %d).@count > 0",                    activetags, [activetags count]]; nspredicate *predicate = [nscompoundpredicate andpredicatewithsubpredicates:@[p1, p2]]; [request setpredicate:predicate]; 

and "trick": left hand side of predicate p2 is

subquery(links, $l, subquery($l.tags, $t, $t.name in %@).@count = %d).@count 

and count of links should included in result, can create expression description predicate:

nsexpression *countexpression = [(nscomparisonpredicate *)p2 leftexpression];  nsexpressiondescription *expressiondescription = [[nsexpressiondescription alloc] init]; expressiondescription.name = @"counter"; expressiondescription.expression = countexpression; expressiondescription.expressionresulttype = nsinteger32attributetype;  [request setresulttype:nsdictionaryresulttype]; [request setpropertiestofetch:@[@"name", expressiondescription]]; 

the resulting sqlite query quite complex. might sensible fetch links first:

nsfetchrequest *linkrequest = [nsfetchrequest fetchrequestwithentityname:@"link"]; nspredicate *linkpredicate = [nspredicate predicatewithformat:@"subquery(tags, $t, $t.name in %@).@count = %d",                               activetags, [activetags count]]; [linkrequest setpredicate:linkpredicate]; nsarray *activelinks = [context executefetchrequest:linkrequest error:&error]; 

and fetch tags in separate step, can done above code predicate p2 replace simpler subquery

nspredicate *p2 = [nspredicate predicatewithformat:@"subquery(links, $l, $l in %@).@count > 0", activelinks]; 

Comments

Popular posts from this blog

plot - Remove Objects from Legend When You Have Also Used Fit, Matlab -

java - Why does my date parsing return a weird date? -

Need help in packaging app using TideSDK on Windows -