Composite key match

57 views
Skip to first unread message

wbi...@attic.nl

unread,
Dec 19, 2014, 5:48:57 AM12/19/14
to mobile-c...@googlegroups.com
I'm having trouble doing a query on a combination of a string ("doctype") and an int ("id").
I have the following mapfunction:

[self.viewByDocTypeAndId setMapBlock: MAPBLOCK({
    if (doc[@"doctype"] != nil && doc[@"id"] != nil) {
        emit(@[doc[@"doctype"], doc[@"id"]], doc);
    }
}) version: @"1.5"];

Given this data (there a several documents that have these properties):
NSString *doctype = @"tablemap";
int id = 193;

This logs nothing:
CBLQuery* query = [databaseManager.viewByDocTypeAndId createQuery];
query.keys = @[doctype, @(id)];
for (CBLQueryRow * queryRow in [query run: &error]) {
    NSLog(@"%@", queryRow.value);
}

And this does:
query = [databaseManager.viewByDocTypeAndId createQuery];
for (CBLQueryRow * queryRow in [query run: &error]) {
    if ([queryRow.value[@"doctype"] isEqualToString: doctype] && [queryRow.value[@"id"] intValue] == id)
        NSLog(@"%@", queryRow.value);
}

Why does the first query return zero matches ? Is my map function wrong ? The .keys ? Or both ?

ajres

unread,
Dec 19, 2014, 7:04:34 AM12/19/14
to mobile-c...@googlegroups.com
I think query.keys is going to filter based on the original document id's not the emitted keys.

If you want to only pull rows that match a specific composite key, try:

query.startKey = @[doctype, @(id)];
query.endKey = @[doctype, @(id)];

wbi...@attic.nl

unread,
Dec 19, 2014, 7:49:02 AM12/19/14
to mobile-c...@googlegroups.com
Using startKey/endKey works, thanks.
I do not understand why .keys doesn't. 
I thought .keys was for an exact match and .startKey/.endKey for a range or wildcard match.

[... reading docs ...]

  • keys: An optional array of document IDs. If given, only keys emitted by the documents with these IDs will be returned (and startKey and endKey will be ignored.)
I completely misunderstood .keys. I try to feel better by thinking that ".keys" is a rather bad name - wouldn't "ids" or "documentIds" be much better ?

Jens Alfke

unread,
Dec 19, 2014, 11:42:52 AM12/19/14
to mobile-c...@googlegroups.com

On Dec 19, 2014, at 2:48 AM, wbi...@attic.nl wrote:

query.keys = @[doctype, @(id)];

That value is a single key, since your view's keys are arrays. You need to wrap it in an array:

query.keys = @[ @[doctype, @(id)] ];


On Dec 19, 2014, at 4:04 AM, ajres <an...@couchbase.com> wrote:

I think query.keys is going to filter based on the original document id's not the emitted keys.

No, it uses the emitted keys. (You're probably thinking of _all_docs, in which the keys are the doc _ids.)

—Jens
Reply all
Reply to author
Forward
0 new messages