Over the weekend I experimentally added support for customizing the ordering of 
the rows in a CBLQueryEnumerator. You can try this out; it’s in a branch called 
“feature/query” in the couchbase-lite-ios repo. (This branch is based on 
master, so it’s significantly ahead of 1.0.1.)

The map/reduce view always returns results ordered by key, because that’s the 
way the underlying index is ordered. But it can be useful to order the results 
of a query in some different order. This adds the ability to do that, by adding 
a property CBLQuery.sortDescriptors. The value must be an array of 
NSSortDescriptor objects, each of which specifies a key-path (relative to the 
CBLQueryRow), an ordering flag, and optionally a comparator. If you’ve done 
much Cocoa programming you’ve probably used NSSortDescriptors already; they’re 
used in table views and CoreData, for instance.

So: If you set a CBLQuery’s sortDescriptors property to a non-nil value, the 
query results will be post-processed (in memory) to sort them according to 
those descriptors. You can also change the sort order after the fact by calling 
-[CBLQueryEnumerator sortUsingDescriptors:] (with some limitations; see the 
header comment on that method for details.)

The key paths in the sort descriptors are relative to the CBLQueryRow objects 
being sorted, so usually they’ll start with “value” or “key”. For example, if 
your view’s values are dictionaries with a “height” property, you can use the 
key-path “value.height” to sort by that. Since keys and values are often 
arrays, but for some reason key-paths don’t handle arrays, I added a hack that 
lets you start a key-path with “key[n]” or “value[n]” where n is an index from 
0–3.

Example:
        // Find pants in sizes 30–34, sorted by length:
        CBLQuery* query = [[db viewNamed: @"pants/by-size"] createQuery];
        query.startKey = @30;
        query.endKey = @34;
        query.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey: 
@"value.length" ascending: YES]];
        CBLQueryEnumerator* e = [query run: &error];

Some performance notes:
The sorting happens in memory, as an extra step, so it’s slower than the 
default by-key sort.
It’s possible to use document properties directly in the key-path (i.e. start 
it with “document.”) but I don’t recommend it since it will cause all of the 
documents to be dragged into memory. If a property is important enough that you 
need to sort by it, it should at least be emitted into the value.
For best performance and scalability, avoid using this; instead create another 
view whose keys include the thing you want to sort by. But it’s not always 
possible to do this; sometimes you really need to specify a key range one way 
and then sort a different way. That’s what this feature is for.

Also, I should note that this feature is experimental and may not make it into 
a release in its current form. Feedback and suggestions are welcome.

—Jens

-- 
You received this message because you are subscribed to the Google Groups 
"Couchbase Mobile" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/mobile-couchbase/689C36FC-C408-461D-B1A7-622B8093D2C2%40couchbase.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to