Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CouchDB Views: remove duplicates *and* order by time

Based on a great answer to my previous question, I've partially solved a problem I'm having with CouchDB.

This resulted in a new view.

Now, the next thing I need to do is remove duplicates from this view while ordering by date.

For example, here is how I might query that view:

GET http://scoates-test.couchone.com/follow/_design/asset/_view/by_userid_following?endkey=[%22c988a29740241c7d20fc7974be05ec54%22]&startkey=[%22c988a29740241c7d20fc7974be05ec54%22,{}]&descending=true&limit=3

Resulting in this:

HTTP 200 http://scoates-test.couchone.com/follow/_design/asset/_view/by_userid_following
http://scoates-test.couchone.com > $_.json.rows
[ { id: 'c988a29740241c7d20fc7974be067295'
  , key: 
     [ 'c988a29740241c7d20fc7974be05ec54'
     , '2010-11-26T17:00:00.000Z'
     , 'clementine'
     ]
  , value: 
     { _id: 'c988a29740241c7d20fc7974be062ee8'
     , owner: 'c988a29740241c7d20fc7974be05f67d'
     }
  }
, { id: 'c988a29740241c7d20fc7974be068278'
  , key: 
 [ 'c988a29740241c7d20fc7974be05ec54'
     , '2010-11-26T15:00:00.000Z'
     , 'durian'
     ]
  , value: 
     { _id: 'c988a29740241c7d20fc7974be065115'
     , owner: 'c988a29740241c7d20fc7974be060bb4'
     }
  }
, { id: 'c988a29740241c7d20fc7974be068026'
  , key: 
     [ 'c988a29740241c7d20fc7974be05ec54'
     , '2010-11-26T14:00:00.000Z'
     , 'clementine'
     ]
  , value: 
     { _id: 'c988a29740241c7d20fc7974be063b6d'
     , owner: 'c988a29740241c7d20fc7974be05ff71'
     }
  }
]

As you can see, "clementine" shows up twice.

If I change the view to emit the fruit/asset name as the second key (instead of the time), I can change the grouping depth to collapse these, but that doesn't solve my order-by-time requirement. Similarly, with the above setup, I can order by time, but I can't collapse duplicate asset names into single rows (to allow e.g. 10 assets per page).

Unfortunately, this is not a simple question to explain. Maybe this chat transcript will help a little.

Please help. I'm afraid that what I need to do is still not possible.

S

like image 348
scoates Avatar asked Nov 28 '10 20:11

scoates


1 Answers

You can do this using list function. Here is an example to generate a really simple list containing all the owner fields without dupes. You can easily modify it to produce json or xml or anything you want.

Put it into your assets design doc inside the lists.nodupes and use like this: http://admin:[email protected]:5984/follow/_design/assets/_list/nodupes/by_userid_following_reduce?group=true

function(head, req) {
    start({
          "headers": {
          "Content-Type": "text/html"
          }
         });
    var row;
    var dupes = [];
    while(row = getRow()) {
    if (dupes.indexOf(row.key[2]) == -1) {
        dupes.push(row.key[2]);
        send(row.value[0].owner+"<br>");
    }
    } 
}
like image 92
Nek Avatar answered Sep 23 '22 12:09

Nek