How to sort documents by date with CBLView and CBLQuery?

I have an Order document which contains a customerId, productId, and dateOrdered. I want to fetch customer’s first order of a particular product. Below is my CBLView code:

    NSString *type = OrderModel.type;
    NSString *viewName = [type stringByAppendingString:@"CustomerOrdersView"];
    
    CBLView *view = [self.database viewNamed:viewName];
    
    [view setMapBlock: MAPBLOCK({
        
        if ([doc[@"type"] isEqual:OrderModel.type]
            && [doc[@"isActive"] boolValue] == true
            && doc[@"customerId"] != nil
            && doc[@"productId"] != nil) {
            emit(@[doc[@"customerId"], doc[@"productId"]], nil);
        }
        
    }) version:@"4"];

And below is my query code:

    CBLQuery* query = [[self customerOrdersView] createQuery];
    query.keys = @[@[customerId, productId]];
    query.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"value.dateOrdered" ascending:YES]];
    
    NSError *error = nil;
    CBLQueryEnumerator *result = [query run:&error];

However, when I print the dateOrdered values, the results weren’t sorted by dateOrdered. How do I do this? I’m using couchbase-lite 1.3.1.

There is no value.dateOrdered, because you’re emitting nil as the value. Try emitting dateOrdered as the value and sorting by “value”.

I’ve updated my code by adding dateOrdered in the emit. This is my new CBLView code:

    NSString *type = OrderModel.type;
    NSString *viewName = [type stringByAppendingString:@"CustomerOrdersView"];
    
    CBLView *view = [self.database viewNamed:viewName];
    
    [view setMapBlock: MAPBLOCK({
        
        if ([doc[@"type"] isEqual:OrderModel.type]
            && [doc[@"isActive"] boolValue] == true
            && doc[@"customerId"] != nil
            && doc[@"productId"] != nil
            && doc[@"dateOrdered"] != nil) {
            emit(@[doc[@"customerId"], doc[@"productId"]], doc[@"dateOrdered"]);
        }
        
    }) version:@"6"];

And my query code:

    CBLQuery* query = [[self view] createQuery];
    query.keys = @[@[customerId, productId]];
    query.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"value.dateOrdered" ascending:YES]];
    
    NSError *error = nil;
    CBLQueryEnumerator *result = [query run:&error];

However, this time the code crashes…

2017-07-12 09:36:13.267 Suites[2080:45219] *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<__NSCFString 0x60800065b0c0> valueForUndefinedKey:]: this class is not key value coding-compliant for the key dateOrdered.'

I think he means you should use “value” to sort by…not “value.dateOrdered”

It worked! Thanks everyone :smile: