How to filter the Documents Using CBLView?

Hi , I am using Couchbase lite Mobile iOS. My requirement is How to filter the documents by their name contains given string(the string will be given at runtime)?

My doc structure is

  {
    "documentType": "customer"
    "name": "venkat"
    "customerrID": "1002"
     "address": "VSKP"
  }

My view is
func createCustomersView()
{
let getCustView = database.viewNamed(“getcustomers”)

    getCustView.setMapBlock({ (doc, emit) -> Void in
        if doc["documentType"] as? String == "customer" {
            emit([doc["name"]!],nil)
        }
    }, version: "1.3")
}

My query is
{
let query = database.viewNamed(“getcustomers”).createQuery()
let result = try! query.run().allObjects
}
By using the above query I am getting all the docs with documentType = “customer”. How to pass the search string to query to get documents by their name contains given string?

You can use the prefixMatchLevel query option to match part of the key http://developer.couchbase.com/documentation/mobile/current/guides/couchbase-lite/native-api/query/index.html#creating-and-configuring-queries

That way you can query the rows that start with a particular set of characters.

Thank you @jamiltz.
I tried like this but couldn’t get the result.
My query is
{
let query = database.viewNamed(“getcustomers”).createQuery()
query.startKey = “ve”
query.endKey = “ve”
query.prefixMatchLevel = 1
let result = try! query.run().allObjects
}
Can you please provide the code snippet in Swift(iOS)?

That’s correct, you can print the row key with the following. Only the documents where the name property starts with “ve” will be returned.

while let row: CBLQueryRow = result.nextRow() {
    print("Row key \(row.value(forKey: "key"))")
}

Thank you @jamiltz. My requirement is where ever the name property contains the given search string(case insensitive) that document has to be returned. In this case, how to assign the values for startKey and endKey.

Couchbase Lite doesn’t support full text search out of the box. But the iOS SDK has full text search utility classes that leverage the storage engine search capabilities https://github.com/couchbase/couchbase-lite-ios/wiki/Full-Text-Search

Then my CBLView changes to like below
My view is
func createCustomersView()
{
let getCustView = database.viewNamed(“getcustomers”)

getCustView.setMapBlock({ (doc, emit) -> Void in
    if doc["documentType"] as? String == "customer" {
        emit(CBLTextKey(doc["name"] as! String),nil)
    }
}, version: "1.4")

}

My query is
{
let query = database.viewNamed(“getcustomers”).createQuery()
query?.fullTextQuery = "ve"
query?.fullTextSnippets = true
let result = try! query?.run()
while let row:CBLFullTextQueryRow = result?.nextRow() as! CBLFullTextQueryRow? {
print(“Customer name (row.fullText)”);
}
}
With the above code I am not getting any result. I am getting result when I gave the query?.fullTextQuery = “venkat”. Is it possible to search with substring of words? My requirement is where ever the name property contains the given search string or character(case insensitive) that document has to be returned?.

Use "ve*" as the search key. The syntax is defined by the SQLite FTS4 module; you can look up its docs online.

If you just want to match on first or last name, it’s cheaper (and cross-platform) to use a regular view. Split the name property into words and emit each word as a key.

Thank you @jens, For suppose if I split the name property into two words and emit as an array of words as key. My requirement is, For example, we have two documents with names “venkat rao” and “ram venkat”. When I search with “ve” then the query has to return two docs(if either firstname or lastname started with given search string).Then how to set the startKey and endKey values for query? If possible please provide code snippet in Swift(iOS).

Don’t emit an array. Call emit() multiple times, once with each word as the key. Now you have an index of words and can use prefix matching.

OK. Then how to set startKey and endKey values? I read in documentation but
couldn’t understand. Please provide the values here then I can easily
understand. Thanks in advance.

Hello,
I want to do Substring match. Is it possible through REST API of couchbase lite?
I have data which has key of the form id and name. ex “key” : [19,“SDemo Test SL 1”] I want to get data which matches id as 19 as well as substring match in name field through REST API?

Please reply if you know anything.
Thanks in advance.

Substring matches are hard to do efficiently with any type of database, because indexes only make it fast to find a string that starts with something. To do substring matches, you either have to

  • Emit every possible suffix of the string (e.g. “SDemo Test SL 1”, “Demo Test SL 1”, “emo Test SL 1”, “mo Test SL 1”, …), which of course will make your index pretty big;
  • or don’t use an index but instead just brute-force scan through all documents. (This can be workable if there are other criteria that you can apply first that reduce the number of matching documents a lot.)

I am using pagination with “limit” and “skip” on document. Also, there is lots of data reside in view with many different id’s and names. Even if I split it out with word in different view to get matching records, I would probably not get sorted data with name. So basically, search/filter should work but with sorting and pagination too.

Any option to case sensitive matching in REST API params?

I am using pagination with “limit” and “skip” on document. … So basically, search/filter should work but with sorting and pagination too.

I’m not sure what you’re saying here; are you asking a question?

Any option to case sensitive matching in REST API params?

You mean params as in the query strings in the URLs? They are already case sensitive. ?rev= is not the same as ?ReV=, for instance.

I’m not sure what you’re saying here; are you asking a question?
No, its my requirement that I want to search string but sorting should work too.

Any option to case sensitive matching in REST API params?
No, Not Param. If I add startkey=[“19”,“est”]&endkey=["19,“estz”] it gives me a record which matches “eST” too. I dont want to retrieve records which will not matching with case given.

Sorry, key matching is case-insensitive.