2010-11-28 17 views
7

Basé sur une bonne réponse à mon previous question, j'ai partiellement résolu un problème que j'ai avec CouchDB.Vues CouchDB: supprimer les doublons * et * commander par temps

Cela a abouti à a new view.

Maintenant, la prochaine chose que je dois faire est de supprimer les doublons de cette vue tandis que en ordre de date.

Par exemple, voici comment je pourrais interroger ce point de vue:

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

résultant en ceci:

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' 
    } 
    } 
] 

Comme vous pouvez le voir, "clémentine" apparaît deux fois. Si je change la vue pour émettre le nom de fruit/actif comme seconde clé (au lieu de l'heure), je peux changer la profondeur de regroupement pour les réduire, mais cela ne résout pas mon besoin de commande par moment . De même, avec la configuration ci-dessus, je peux commander en fonction du temps, mais je ne peux pas réduire les noms d'actifs en double en une seule ligne (pour autoriser, par exemple, 10 actifs par page).

Malheureusement, ce n'est pas une simple question à expliquer. Peut-être this chat transcript aidera un peu.

Aidez-nous s'il vous plaît. J'ai peur que ce que je dois faire ne soit toujours pas possible.

S

Répondre

7

Vous pouvez le faire en utilisant la fonction de liste. Voici un exemple pour générer une liste très simple contenant tous les champs propriétaires sans dupes. Vous pouvez facilement le modifier pour produire json ou xml ou tout ce que vous voulez.

Mettez-le dans votre conception doc actifs à l'intérieur des lists.nodupes et utiliser comme ceci: 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>"); 
    } 
    } 
} 
+0

Salut. J'ai essayé votre réduire, et je ne pense pas que cela a résolu mon problème: http: // scoates-test.couchone.com/_utils/database.html?follow/_design/asset/_view/by_userid_following_reduce (malgré la réduction, je reçois toujours "banana" deux fois pour "c988a29740241c7d20fc7974be060bb4"). L'ai-je mal appliqué? – scoates

+0

Désolé, mon premier exemple est faux. Cela ne fonctionne que pour les valeurs en double. Pour les clés, vous devez utiliser des listes. J'ai changé l'exemple. J'espère que cela résout votre problème. – Nek

+0

Oh wow. Je n'avais aucune idée que ces fonctions de liste existaient. Je vais essayer et revenir et accepter si cela répond à mes besoins (mais ça en a l'air pour l'instant). Merci! – scoates

2

commande par un champ et uniquing autre n'est pas quelque chose que la carte de base peut réduire le faire. Tout ce qu'il peut faire est de trier vos données, et d'appliquer réduire les cumuls à des plages de clés dynamiques.

Pour trouver la dernière entrée pour chaque type de fruit, vous auriez besoin d'interroger une fois par fruit.

Il y a plusieurs façons de le faire qui sont un peu saines.

Vous voulez une vue avec les clés comme [fruit_type, date], et vous pouvez interroger comme ceci:

for fruit in fruits 
    GET /db/_design/foo/_view/bar?startkey=["apples"]&limit=1&descending=true 

Cela vous donnera la dernière entrée pour chaque fruit.

L'opération de liste pourrait être utilisée pour cela, elle ferait juste écho à la première ligne du bloc de chaque fruit. Ce serait assez efficace tant que chaque fruit a un petit nombre d'entrées. Une fois qu'il y a beaucoup d'entrées par fruit, vous rejetterez plus de données que vous n'en faites écho, de sorte que l'approche multi-requêtes évolue réellement mieux que l'approche par liste, lorsque vous arrivez à un grand ensemble de données. Heureusement, ils peuvent travailler tous les deux sur le même index de vue, donc quand vous devrez changer, ce ne sera pas une grosse affaire.

+0

Le problème que j'ai avec le faire dans deux requêtes est que je ne peux pas raisonnablement paginer les résultats, ce que je dois faire . Dire que j'ai besoin des 3 entrées les plus récentes, et le plus 4 sont: pomme, banane, banane, clémentine, puis si je limite à 3, je recevrais pomme, banane, banane, et je devrais jeter la deuxième banane, laissant seulement 2 résultats. Peut-être que je ne comprends pas. Travailler sur l'idée de la liste de Nek maintenant, et il semble que cela pourrait résoudre mon problème, malgré une mauvaise adaptation si beaucoup de gens ont le même atout (fruit). Merci de prendre le temps de répondre. – scoates