iOS: Get a single item from database

61 views
Skip to first unread message

Horatiu Potra

unread,
Feb 17, 2015, 9:31:20 AM2/17/15
to mobile-c...@googlegroups.com
Hello,

I want to get a single item from the database, but from what I read it's not recommend to capture other external variables(local variables from within the function I set the block) in mapBlock from CBLView. Is this correct ?

Right now I can get all documents of a certain type and after that parse them until I found the item I need. Is there another way to get the item without actually parsing the entire CBLQueryEnumerator ? I know about postFilter property of CBLQuery but I was thinking if there is another way.

Thank you in advance :-)

Jens Alfke

unread,
Feb 17, 2015, 11:29:14 AM2/17/15
to mobile-c...@googlegroups.com
On Feb 17, 2015, at 6:31 AM, Horatiu Potra <horati...@3pillarglobal.com> wrote:

but from what I read it's not recommend to capture other external variables(local variables from within the function I set the block) in mapBlock from CBLView. Is this correct ?

More than not recommended, it will cause bugs. The map function is used to create a persistent index, so if it doesn’t behave the same way every time it’s called, you won’t have a self-consistent index and your view query results won’t make sense.

Right now I can get all documents of a certain type and after that parse them until I found the item I need. Is there another way to get the item without actually parsing the entire CBLQueryEnumerator ? I know about postFilter property of CBLQuery but I was thinking if there is another way.

It depends entirely on what it is you’re looking for in the document, i.e. what the search criteria are. I don’t think I can offer help unless you give some more details…?

—Jens

Horatiu Potra

unread,
Feb 18, 2015, 2:42:44 AM2/18/15
to mobile-c...@googlegroups.com
My CBLModel object has a property string named url. I want to get one single document based on a certain url. This is how I do it now:

    CBLView* view = [database viewNamed:@"cachedResponse"];

   
[view setMapBlock:^(NSDictionary* doc, void (^emit)(id key, id value)){
       
if ([doc[@"type"] isEqualToString:kCachedType]) {
            emit
(doc[@"_id"], doc);
       
}
   
} version: @"1"];    

   
CBLQuery* query = [view createQuery];
    query
.postFilter = [NSPredicate predicateWithFormat:@"value.url = %@", url.absoluteString];

   
NSError *error = nil;
   
CBLQueryEnumerator *enumerator = [query run:&error];

   
if (error) {
       
NSLog(@"Error running query: %@", error.description);
       
return nil;
   
}

   
if (enumerator.count == 0) {
       
return nil;
   
}

   
CBLQueryRow *row = [enumerator rowAtIndex:0];
   
MPCachedCBLResponse *response = [MPCachedCBLResponse modelForDocument:row.document];


From what I read in documentation the postFilter predicate is ran after the map block is ran, is this correct ? Do you know some other ideas on how to get that single CBLModel object that has the url search criteria ? 


Jens Alfke

unread,
Feb 18, 2015, 11:23:12 AM2/18/15
to mobile-c...@googlegroups.com

On Feb 17, 2015, at 11:42 PM, Horatiu Potra <horati...@3pillarglobal.com> wrote:

My CBLModel object has a property string named url. I want to get one single document based on a certain url.

Make a view whose map function checks that the doc is of the desired type, then emits the url property as the key: emit(doc[@“url”], nil)
Create a query on that view.
Set the startKey and endKey properties to the URL string you’re looking for.

In general, a view’s map function will check that the doc matches the criteria, then emit the thing you’re searching for as the key. Then you query for the range of keys you want.

—Jens

Horatiu Potra

unread,
Feb 19, 2015, 2:16:41 AM2/19/15
to mobile-c...@googlegroups.com
Thank you Jens Alfke :-)
Reply all
Reply to author
Forward
0 new messages