New to couchbase how to make "view" of a doc.?


#1

1-
“results”: [
{
“cms”: {
"_active": true,
"_createdAt": 1462285286025,
"_createdBy": “admin”,
"_modifiedAt": 1462285286025,
"_modifiedBy": “admin”,
"_type": “Attribute”,
“mandatory”: false,
“name”: “#$^\u0026(lamp)+!~\u003e\u003cfish”,
“searchable”: true,
“visible”: false
}
}
],

2-
“cms”: {
"_active": true,
"_createdAt": 1465395192617,
"_createdBy": “admin”,
"_modifiedAt": 1465395192617,
"_modifiedBy": “admin”,
"_type": “Product”,
“attributes”: {
“clutch”: “ibn”,
“pen”: “cello”,
“plastic-cup”: “havels”,
“title”: "ibn havels cello "
},
“brand”: “koovs”,
“categories”: [
“145”
],
“images”: [],
“status”: “OFFLINE”
}
}
],

we have many types of docs in our system 1 one is the doc for attribute which has unique id and name ,2nd is doc for the product.Now the problem is that i have to make a VIEW
WHICH CONTAINS [AttributeId(key) -> and List(value)] ,List of products for that specific attribute id . I have no idea where to start can some1 please guide me .


#2

Can you get the attribute id (or whatever it is that you want to query with) from within the Product document? (looks like the attributes object is a good candidate).

If so, you can emit several times in your view’s map function. So you’d loop on all the attributes of a Product and emit(attribute, null)

With that kind of view, you’ll be able to query the view with a key of foo and get all the products that have the attribute foo.

Please refer to the developer’s guide view basics and writing views sections to learn more about how to build views.

PS: there is also the N1QL alternative, which might be more natural to you if you’ve done some SQL.


#3

can u please give an example.i can’t get u clearly, and yes i can get attributeId from productDoc.how to loop over the attributes,means is it different from (Attribute attr : attributes) type and since there is map of attributes in product.i am new to this pls explain


#4

Views are based on javascript functions (“map function”) that extract an attribute of the document (the “key” for querying the view), and optionally some data (but not the whole document).

You write the map function, and call emit(keyValue, data) (often the simple version emit(keyValue, null)) as many times as required. Each call to emit adds an entry in the view’s index that maps keyValue to the doc being indexed (so you can always recover the document).

If you want to query your product by attribute, you have to decide on a usable format for the view key: how do you want to query? Since attributes seems to be an object, it could be eg. the attribute name + its value separated by a dash: pen-cello.

function(doc, meta) {
  //this ensure we're only indexing products, with attributes
  if (doc._type == "Product" && doc.attributes)  {
    //we loop on attributes key-value pairs
    for (var attr in doc.attributes) {
      //we index this particular document under the "attributeName-attributeValue" key
        emit(attr + '-' + doc.attributes[attr], null);
    }
  }
}

#5

thanks a lot for the reply.
public List findByAttribute(List attrIds, Integer page, Integer size) {

    String viewName = "products_by_name";
    String mapFunction = "function (doc, meta) {\n"
            + " if(doc._type && doc._type == \"Product\" && doc.attributes) {\n"
            + "     for(var attrIds in doc.attributes){\n"
            + "    emit(doc.name, null);\n"
            + "  }\n" 
            + "}\n"
            +"}";
    DesignDocument designDoc = new DesignDocument("product_by_name");

    ViewDesign view = new ViewDesign(viewName, mapFunction);
    designDoc.getViews().add(view);
    return findByView(designDoc.getName() , view.getName(), attrIds ,page ,size);

is this is a right way to create view in java.?? I have to import import com.couchbase.client.protocol.views.ViewDesign; package.
what if i have to do the same work for category which is a arraylist.


#6

This is the right way to create the design document in the Java SDK 1.4.x version (which by the way is now end of life) but you’re missing the step to save it on the server.

Views are not something client side (once again, please refer to the general documentation provided above). So you have to upload the design document (which should usually group several views) to the server and let it index docs:

//with CouchbaseClient client
client.createDesignDoc(designDoc);

:warning: Note: when you wish to update a design document with a new view, you should always make sure that the designDoc contains the whole list of exisiting ViewDesign, as it will replace what exists on the server (so you might lose some views otherwise)…

ALSO the map function is incorrect I think: the for loop is unnecessary if all you want is to query by name, a Product has only one name, so it should only call emit once.

Note that emit first parameter should be the value by which you want to query later on, which you can also construct from multiple attributes of the document (as I did in my example in the for loop: basically query by attribute key-value pairs). So if you want to be able to query by categories, just loop on the categories and emit each of them.

:bulb: tip: The webconsole lets you define your views and toy around a bit with a subset of the documents, see what the view produces (development mode) before publishing to production mode, so that could be handy, even if you want to tinker with the view definition locally.


#7

I have made views for both [products by attributeId] and [categories by attributeId] but it is not fast in fetching data,now what to do for fast read ,someone told me that GSI indexes are fast for read lookups.
Now on what entity do i need to make GSI index for getting [products by attributeIDs] where attribute is a Map and **products by categoryId where category is a list.**Please reply.


#8

N1QL with GSI indexes could be a good option too, as I said earlier, yes. You’d need a Couchbase Server version 4.0 or above (and I suspect that for your particular use case you might need array indexes, which are being introduced in Couchbase Server 4.5).

Indexes (like views, N1QL indexes through GSI, etc…) are usually managed on the server side, using the webconsole ou command line tools, like cbq.

:warning: Our support and SEs discourage their creation in the applicative code (the SDK still offers that option though).

  1. Please refer to the documentation to learn how to create N1QL indexes.
  2. Open a topic in the N1QL section of this forum to get help on coming up with the right N1QL query, and creating the right index for your query.

These are not Java SDK specifics, although the part where you’ll execute your query will be.
Executing a N1QL query in the SDK is basically done like this:

N1qlQuery query = N1qlQuery.simple("SELECT something FROM fakequery"); //replace with your query
N1qlQueryResult result = bucket.query(query);