2010-06-04 7 views

Antwort

47

Die in-place Beispielfunktion ist nicht das gleiche wie "in-place" Updates in anderen Datenbanken. CouchDB verwendet immer noch eine Append-Only-Architektur; Dokument-Update Handler immer noch eine neue doc-Revision, etc.

noch Update-Handler sind sehr praktisch und es lohnt sich zu lernen.

Angenommen, Sie haben ein Dokument mit einem Akkumulator. Sie möchten eine Ganzzahl in einem Dokument mit nur einer HTTP-Abfrage akkumulieren, wobei die Inkrementmenge unter Verwendung eines amount-Parameters angegeben wird. Betrachten Sie die folgenden Befehle:

curl -X PUT http://localhost:5984/db 
# Returns {"ok":true} 

curl -H "Content-Type:application/json" -X POST http://localhost:5984/db/_bulk_docs -d @- 
{"docs": 
    [ 
    {"_id": "my_doc", "number": 23}, 
    {"_id": "_design/app", 
     "updates": { 
     "accumulate": "function (doc, req) { 
         var inc_amount = parseInt(req.query.amount); 
         doc.number = doc.number + inc_amount; 
         return [doc, \"I incremented \" + 
             doc._id + \" by \" + 
             inc_amount]; 
         }" 
     } 
    } 
    ] 
} 
# Returns [{"id":"my_doc","rev":"1-8c9c19a45a7e2dac735005bbe301eb15"}, 
#   {"id":"_design/app","rev":"1-83ec85978d1ed32ee741ce767c83d06e"}] 

(Denken Sie daran, End-of-Datei zu drücken,^D, nach dem JSON-Objekt in der POST.)

Weiter bestätigen das Dokument für die Akkumulation (my_doc) vorhanden ist:

curl http://localhost:5984/db/my_doc 
# Returns {"_id":"my_doc","_rev":"1-8c9c19a45a7e2dac735005bbe301eb15", 
#   "number":23} 

Jetzt können Sie die accumulate Handler Update rufen mit einem amount Parameter Update das Feld ein.

curl -X PUT \ 
http://localhost:5984/db/_design/app/_update/accumulate/my_doc?amount=15 
# Returns: I incremented my_doc by 15 

curl http://localhost:5984/db/my_doc 
# Returns {"_id":"my_doc","_rev":"2-<whatever>", 
#   "number":38} 

Beachten Sie, dass der neue number Wert 38 ist, wird der Wert von 23 + 15.

+0

Der _rev-Wert erhöht jedoch auf Updates. –

+0

Whoops, behoben. Vielen Dank. – JasonSmith

2

Hier ist etwas, was ich als sehr nützlich, wenn sie mit dem obigen Beispiel zu spielen. Sobald Sie einen Update-Handler installiert haben, können Sie ihn verwenden, um den Update-Handler selbst zu aktualisieren. wenn Ihr Update-Handler in update.json Zum Beispiel ist, können Sie wie folgt vorgehen:

curl --dump-header - -H "Content-Type:application/json" -X POST http://localhost:5984/db/_design/app/_update/modifyinplace/_design/app -d @update.json 

wo update.json enthält:

{"_id": "_design/app", 
    "updates": { 
     "modifyinplace": "function (doc, req) { var fields = JSON.parse(req.body); for (var i in fields) { doc[i] = fields[i] } var resp = eval(uneval(doc)); delete resp._revisions; return [doc, toJSON(resp)]; }" 
    } 
} 

Ein paar Dinge sind bemerkenswert. Die Aussage var resp = eval(uneval(doc)) Klone doc. Es gibt mehr information on cloning here. Da das Feld _revisions groß werden kann, ist das Löschen in der Antwort für meinen Anwendungsfall sinnvoll. Die Verwendung von toJSON(resp) sendet die Antwort als Zeichenfolge zurück, jedoch ist der Wert _rev in einer erfolgreichen Antwort falsch. Um die korrekte Revision eines erfolgreichen Updates zu erhalten, sehen Sie sich X-Couch-Update-NewRev im Antwortheader an. Das Update konnte sehr wahrscheinlich nicht erfolgreich sein und zu einem Konflikt führen, as addressed here