2010-06-04 8 views

risposta

47

La funzione di esempio in-place non è lo stesso di aggiornamenti "in-place" in altre database. CouchDB utilizza ancora un'architettura solo append; gli aggiornamenti del documento gestiscono ancora una nuova revisione del documento, ecc.

Ancora, i gestori di aggiornamento sono abbastanza convenienti e meritano di essere appresi.

Supponiamo di avere un documento con un accumulatore. Si si desidera accumulare un numero intero in un documento con una sola query HTTP, specificando l'importo dell'incremento utilizzando un parametro amount. Prendere in considerazione i seguenti comandi:

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

(ricordarsi di premere end-of-file,^D, dopo che l'oggetto JSON nel post.)

Avanti confermare il documento per l'accumulo (my_doc) esiste:

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

Ora è possibile chiamare il gestore accumulate aggiornamento con una amount parametro aggiornare il campo.

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} 

Si noti che il nuovo valore number è 38, il valore di 23 + 15.

+0

Il valore _rev incrementa tuttavia sugli aggiornamenti. –

+0

Whoops, risolto. Grazie. – JasonSmith

2

Ecco qualcosa che ho trovato molto utile quando si gioca con l'esempio precedente. Una volta installato un gestore di aggiornamento, è possibile utilizzarlo per aggiornare lo stesso gestore di aggiornamento. Ad esempio, se il gestore di aggiornamento è in update.json, si potrebbe fare la seguente:

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

dove update.json contiene:

{"_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)]; }" 
    } 
} 

Un paio di cose sono degni di nota. La dichiarazione var resp = eval(uneval(doc)) cloni doc. C'è più information on cloning here. Poiché il campo _revisions può diventare grande, l'eliminazione nella risposta ha senso per il mio caso d'uso. L'utilizzo di toJSON(resp) restituisce la risposta come stringa, tuttavia, il valore di _rev in una risposta corretta sarà errato. Per ottenere la corretta revisione di un aggiornamento riuscito, consultare X-Couch-Update-NewRev nell'intestazione della risposta. L'aggiornamento potrebbe non avere esito positivo e causare un conflitto, as addressed here

Problemi correlati