Filter Documents - how?!

39 views
Skip to first unread message

Marco Betschart

unread,
Aug 4, 2015, 11:52:03 AM8/4/15
to Couchbase Mobile
Hi @all!

Couchbase Lite is driving me nuts at the moment :(
I try to achieve a simple filtering on the stored person documents which mets the following criterias:

- I got multiple optional filter criterias such as "Name", "Gender" or "Group"
- The sort order should be [firstName,lastName]

The Person Model looks like the following (as for now only testing with "gender"):

@objc(Person)


class Person: CBLModel{

       @NSManaged var firstName: NSString?

       @NSManaged var lastName: NSString?

       @NSManaged var gender: Label?

        @NSManaged var groups: NSArray?

       class func groupsItemClass() -> AnyClass{

               return Group.self

       }
}


And my view map function looks like:

{ (doc, emit) -> Void in

       if (doc["type"] as? String) == "Person" {

              var key: [AnyObject] = []

              var params = [String:AnyObject]()


                if let gender = doc["gender"] as? String{

                      params["gender"] = gender

              }

              key.append(params)

             

               if let firstName = doc["firstName"] as? String{

                key.append(firstName)

          } else {

                       key.append("")

         }

             

                if let lastName = doc["lastName"] as? String{

                  key.append(lastName)

           } else {

                       key.append("")

         }


          emit(key,nil)

    }

}



Basically my idea was to use a dictionary as the first view param, since in the docs I read somewhere it's order is undefined.
And afterwards use "firstName" and "lastName" for the sort in the view key.

But unfortunately it doesn't work :(

How to solve this issue, so I'm able to call a function with optional filter params?
The goal should look something like this:

func filter(params: [String:AnyObject]? = nil) -> CBLQueryEnumerator



Jens Alfke

unread,
Aug 4, 2015, 12:46:18 PM8/4/15
to mobile-c...@googlegroups.com

On Aug 4, 2015, at 12:59 AM, Marco Betschart <marbe...@gmail.com> wrote:

- I got multiple optional filter criterias such as "Name", "Gender" or "Group"
- The sort order should be [firstName,lastName]

This kind of query is too complex for a view to do on its own. The problem is that you’re selecting based on different criteria than you’re sorting on. (This is true of any index; SQL databases have the same constraints but the query engine works around it.)

The best approach is to define the view so you can efficiently filter, and then add a custom sortDescriptor to the query. This will do the sorting in memory, but it should be fast enough unless the query returns a huge number of rows.

Sorting by multiple optional criteria can be tricky. You won’t be able to do all combinations of name/gender/group filtering using a single index. (Again, this is true of any kind of index.) It’ll require multiple views.

Have you looked at CBLQueryBuilder? It should be able to do what you’re asking. You specify the filter criteria as an NSPredicate and the sort order as an NSSortDescriptor, and it generates a view and does any custom sorting. (We don’t have official docs for it yet but the wiki page I linked to should be enough to get you started. Feel free to ask questions here.)

—Jens
Reply all
Reply to author
Forward
0 new messages