2010-11-28 4 views
7

Basierend auf einer tollen Antwort auf meine previous question, habe ich ein Problem mit CouchDB teilweise gelöst.CouchDB Aufrufe: Duplikate entfernen * und * nach Uhrzeit sortieren

Dies ergab a new view.

Nun, das nächste, was ich tun muss, ist das Entfernen von Duplikaten aus dieser Ansicht während nach Datum sortiert.

Zum Beispiel, hier ist, wie ich diese Ansicht abfragen könnte:

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

Resultierende in dieser:

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

Wie Sie sehen können, "Clementine" zeigt zweimal auf.

Wenn ich die Ansicht ändere, um den Namen der Frucht/Anlage als zweiten Schlüssel (anstelle der Zeit) auszugeben, kann ich die Gruppierungstiefe ändern, um diese zusammenzufallen, aber das löst meine Anforderung nach Zeit nicht . In ähnlicher Weise kann ich mit der obigen Einstellung nach Zeit sortieren, aber ich kann doppelte Asset-Namen nicht in einzelne Zeilen zusammenfassen (um beispielsweise 10 Assets pro Seite zuzulassen).

Leider ist dies keine einfache Frage zu erklären. Vielleicht wird this chat transcript ein wenig helfen.

Bitte helfen. Ich fürchte, dass das, was ich tun muss, immer noch nicht möglich ist.

S

Antwort

7

Sie können dies mithilfe der Listenfunktion tun. Hier ist ein Beispiel, um eine wirklich einfache Liste zu erstellen, die alle Besitzerfelder ohne Duplikate enthält. Sie können es leicht ändern, um json oder xml oder irgendetwas, das Sie wünschen, zu produzieren.

Legen Sie es in Ihr Vermögen Design doc innerhalb der lists.nodupes und verwenden wie folgt aus: 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

Hallo. Ich habe versucht, reduzieren, und ich glaube nicht, dass es mein Problem gelöst: http: // scoates-test.couchone.com/_utils/database.html?follow/_design/asset/_view/by_userid_following_reduce (trotz der Reduzierung, bekomme ich immer noch "Banane" zweimal für "c988a29740241c7d20fc7974be060bb4"). Habe ich es falsch implementiert? – scoates

+0

Sorry, mein erstes Beispiel ist falsch. Es funktioniert nur für doppelte Werte. Für Schlüssel müssen Sie Listen verwenden. Ich habe das Beispiel geändert. Hoffe es löst dein Problem. – Nek

+0

Oh wow. Ich hatte keine Ahnung, dass diese _list-Funktionen überhaupt existierten. Ich werde es versuchen und zurückkommen und akzeptieren, wenn es meinen Bedürfnissen entspricht (aber es sieht an diesem Punkt so aus). Vielen Dank! – scoates

2

Bestellung durch ein Feld und auf einem anderen uniquing ist nicht etwas, das Basiskarte tun reduzieren. Sie können nur Ihre Daten sortieren und Rollups auf dynamische Schlüsselbereiche anwenden.

Um den neuesten Eintrag für jede Art von Obst zu finden, müssen Sie einmal pro Obst abfragen.

Es gibt einige Möglichkeiten, dies zu tun, die irgendwie gesund sind.

Sie erhalten eine Ansicht mit den Tasten wie [fruit_type, Datum], wollen und dann können Sie wie folgt abfragen:

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

Diese Sie für jede Frucht die neueste Eintrag geben.

Die Liste Operation könnte dazu verwendet werden, würde es nur die erste Zeile aus jeder Frucht Block widerhallen. Dies wäre effizient genug, solange jede Frucht eine kleine Anzahl von Einträgen aufweist. Sobald es viele Einträge pro Frucht gibt, werden Sie mehr Daten verwerfen, als Sie zurückgeben, so dass der Multi-Abfrage-Ansatz tatsächlich besser skaliert als der Listenansatz, wenn Sie zu einem großen Datensatz gelangen. Glücklicherweise können sie beide auf dem gleichen Ansichtsindex arbeiten, also wenn Sie umschalten müssen, wird es keine große Sache sein.

+0

Das Problem, das ich damit in zwei Abfragen habe, ist, dass ich die Ergebnisse nicht paginieren kann, was ich tun muss . Sagen wir, ich brauche die letzten 3 Einträge, und die meisten 4 sind: Apfel, Banane, Banane, Clementine, dann, wenn ich auf 3 beschränke, würde ich Apfel, Banane, Banane bekommen und müsste die zweite Banane wegwerfen und gehen nur 2 Ergebnisse. Vielleicht verstehe ich einfach nicht. Jetzt arbeite ich an Neks List-Idee, und es scheint, als könnte es mein Problem lösen, obwohl ich nicht gut skalieren kann, wenn viele Leute den gleichen Wert haben (Früchte). Danke, dass Sie sich die Zeit genommen haben, zu antworten. – scoates