Search code examples
javapaginationcouchdbektorp

Fetch Paginated view data after applying reduce in couchdb with ektorp


Hi I want to fetch data from couchdb-view by applying reduce and pagination.

My view gives reduce function result as complex key as follows

{"rows":[
         {"key":{"attribute":"Attribute1"},"value":20},
         {"key":{"attribute":"Attribute2"},"value":1}
         {"key":{"attribute":"Attribute3"},"value":1}
]}

I am trying to fetch data from couchdb using ektorp, check following code

PageRequest pageRequest = PageRequest.firstPage(10);
ViewQuery query = new ViewQuery()
            .designDocId("_design/medesign")
            .viewName("viewname")
            .includeDocs(false)
            .reduce(true)
            .group(true);
Page<ViewResult> rs1 = db.queryForPage(query, pageRequest, ViewResult.class);

rs1.forEach(v -> {
            System.out.println(v.getSize());
        });

I am getting following error

org.ektorp.DbAccessException: com.fasterxml.jackson.databind.JsonMappingException: 
Can not construct instance of org.ektorp.ViewResult: 
no int/Int-argument constructor/factory method to deserialize from Number value (20)
at [Source: N/A; line: -1, column: -1]

Solution

  • CouchDB doesn't Give paginated details if you want paginated reduced data.

    Request with paginated include docs
    group=false & reduce=false & include_docs=true

    URL : http://localhost:5984/dn_anme/_design/design_name/_view/viewname?include_docs=true&reduce=false&skip=0&group=false&limit=2

    Response :

    {
       "total_rows":81,
       "offset":0,
       "rows":[
          {
             "id":"906a74b8019716f1240a7117580ec172",
             "key":{
                "attribute":"BuildArea"
             },
             "value":1,
             "doc":{
                "_id":"906a74b8019716f1240a7117580ec172",
                "_rev":"3-7e0a1da0c2260040f8a9787636385785",
                "country":"POL",            
                "recordStatus":"MATCHED"
             }
          },
          {
             "id":"906a74b8019716f1240a7117580eaefb",
             "key":{
                "attribute":"Area",
             },
             "value":1,
             "doc":{
                "_id":"906a74b8019716f1240a7117580eaefb",
                "_rev":"3-165ea3a3ed07ad8cce1f3e095cd476b5",
                "country":"POL",
                "recordStatus":"MATCHED"
             }
          }
       ]
    }
    

    Request with Reduce group=true& reduce=true& include_docs=false

    URL : http://localhost:5984/dn_anme/_design/design_name/_view/viewname?include_docs=false&reduce=true&group=true&limit=2

    Resoonse :

    {
       "rows":[
          {
             "key":[
                "BuildArea"
             ],
             "value":1
          },
          {
             "key":[
                "Area"
             ],
             "value":1
          }
       ]
    }
    

    Difference in between both Request:
    Request with paginated include docs gives page data {"total_rows":81, "offset":0, rows":[{...},{...}]} AND Request with reduce give {"rows":[{...},{..}]}

    How you can get paginated reduce data:

    Step 1: Request rows_per_page + 1 rows from the view
    Step 2: if in response one extra records than page_size then there are more records
    Step 3: calculate and update skip value and got to step 1 for next page
    Note: adding skip is not good option for lots of records instead of that find start key and add start key, its good for better perforamance