mindas
mindas

Reputation: 26733

How to retrieve data by document key in couchbase

Suppose we have a document which is stored in couchbase:

{
   "type": "Application",
   "policies": [
       "p1",
       "p2"
   ],
   "title": "app1",
   "uuid": "03765cd7-4dcd-4ed0-9586-05acf2e845ad"
}

I have created a view which emits all policies:

function (doc, meta) {
  if (doc.type && doc.type == "Application") {
    for (var i in doc.policies) {
      emit(doc.policies[i], doc.title);
    }
  }
}

To test this I queried localhost:8092/default/_design/dev_DesignName/_view/ViewName?stale=false&inclusive_end=false&connection_timeout=60000&limit=10&skip=0 which successfully listed

{"total_rows":2,"rows":[
  {"id":"03765cd7-4dcd-4ed0-9586-05acf2e845ad","key":"p1","value":"app1"},
  {"id":"03765cd7-4dcd-4ed0-9586-05acf2e845ad","key":"p2","value":"app1"}
]}

So far so good.

Question: how to filter results by, say, key=p1?

I tried various query suffix combinations, including:

None of these worked - first three because of JSON syntax errors while the last one just resulted empty result. What am I missing?

Bonus question: having this configuration, what's the best possible way to do set intersection, i.e.

Then

EDIT: it turns out querying by String key works with Java API (correct rows are brought back). Still it would be interesting to know what was I missing in my REST API attempts.

Upvotes: 0

Views: 3471

Answers (2)

avsej
avsej

Reputation: 3972

Answer

key="p1" is the right thing to try, because the key have to be valid JSON, and because you are emitting strings here, it should be double-quoted. But it seems like key sensitive to inclusive_end parameter, which is false by default when you are designing your queries in the UI. So just uncheck it here to see your key:

View Query Parameters UI

Bonus Answer

Implement OR is quite easy here, just enumerate keys using keys= argument:

$ curl 'http://localhost:8092/default/_design/test/_view/test?inclusive_end=true&keys=%5B"p2","p3"%5D'
{"total_rows":6,"rows":[
{"id":"03765cd7-4dcd-4ed0-9586-05acf2e845a1","key":"p2","value":"app2"},
{"id":"03765cd7-4dcd-4ed0-9586-05acf2e845ad","key":"p2","value":"app1"},
{"id":"03765cd7-4dcd-4ed0-9586-05acf2e845a1","key":"p3","value":"app2"},
{"id":"03765cd7-4dcd-4ed0-9586-05acf2e845a2","key":"p3","value":"app2"}
]
}

keys argument, should be also valid JSON, here ["p2","p3"]. When you are using POST request, you don't have to URLencode it. And of course you don't have to play with these encoding when you are setting keys through its API:

ViewQuery query = ViewQuery.from("test", "test")
        .keys(JsonArray.empty().add("p2").add("p3"));

But implementing AND will be trickier a bit, but also possible if you will modify your view instead of emitting once per single policy, your mapper should generate all possible combinations and they you need to specify needed requirement in your query. To reduce space, your application might assume that both key sets and query in this case will be ordered.

Upvotes: 2

Austin Gonyou
Austin Gonyou

Reputation: 252

As the previous user described. You can test all this in the Couchbase Administrative UI under the Views->Development Views for a given bucket. It will also generate a REST Query you can use to test. You might also want to experiment a bit with "startKey" and "endKey". I'm putting together a blog post and will publish here once done complete with a couple examples and N1QL.

Upvotes: 0

Related Questions