ios - How do I set up relationship for large core data sets efficiently? -
i have 2 entities drink , breweries. have data in json , building out core data tables each , have relationship set (one 1 drink brewery). however, trying set @ time of building out drink objects slows down process because having query core data every time create new drink (there couple thousand drinks , 1000 breweries). @ moment brewery has unique id matches attribute on drink. best way go without slowing down load time greatly? considering using 1 entity instead , placing breweries in same table though bad db practice.
here code building out drink table json code adding in brewery commented out.
[jsoncategories enumerateobjectsusingblock:^(id obj, nsuinteger idx, bool *stop){ drink *drink = [nsentitydescription insertnewobjectforentityforname:@"drink" inmanagedobjectcontext:importcontext]; //drinktype.id = [obj objectforkey:@"id"]; drink.name = [obj objectforkey:@"name"]; drink.alcoholbyvolume = [obj objectforkey:@"abv"]; drink.drinktype = beerdrinktype; drink.breweryid = [obj objectforkey:@"brewery_id"]; // nsarray *fetchedobjects; // nsfetchrequest *fetch = [[nsfetchrequest alloc]init]; // nsentitydescription *entitydescription = [nsentitydescription entityforname:@"breweries" inmanagedobjectcontext:importcontext]; // [fetch setentity:entitydescription]; // [fetch setpredicate:[nspredicate predicatewithformat:@"id =%@", drink.breweryid]]; // nserror *errorbrewery; // [fetch setfetchlimit:1]; // fetchedobjects = [importcontext executefetchrequest:fetch error:&errorbrewery]; // if (fetchedobjects && [fetchedobjects count] > 0){ // breweries *fetchedbrewery = [fetchedobjects objectatindex:0]; // drink.breweries = fetchedbrewery; // } }];
you re-fetching brewery list each iteration of jsoncategories elements. adds huge overhead , causes slowness, , unnecessary because assume list not change.
a better design fetch once, , filter needed. i’ve omitted code below , wrote important parts, should able fill in yourself.
nsfetchrequest *fetch = …; // note predicate not set here fetchedbreweries = [importcontext executefetchrequest…]; [jsoncategories enumerateobjectsusingblock:^(id obj, nsuinteger idx, bool *stop){ … nsarray *matchingbreweries = [fetchedbreweries filteredarrayusingpredicate:…predicate]; drink.breweries = matchingbreweries.firstobject; }];
maybe slow, because if fetch breweries, might consume cpu , memory (though i’d first try see if problem).
a further optimization first iterate on jsoncategories , create set of brewery id-s found in results. then, fetch these breweries, , iterate on drink results again add breweries drinks. like
nsmutableset *breweryids = [nsmutableset set]; [jsoncategories enumerateobjectsusingblock:^(id obj, nsuinteger idx, bool *stop){ … [breweryids addobject:[obj objectforkey:@"brewery_id"]]; }]; nsfetchrequest *fetch = [[nsfetchrequest alloc] init]; [fetch setpredicate:[nspredicate predicatewithformat:@"id in %@", breweryids]]; nsarray *breweries = [importcontext executefetchrequest…] (drink *drink in drinks) { nsarray *matchingbreweries = [fetchedbreweries filteredarrayusingpredicate:…predicate]; drink.breweries = matchingbreweries.firstobject; }
hm. need beer now.
Comments
Post a Comment