web-dev-qa-db-ja.com

CouchDBドキュメント更新ハンドラー(インプレース更新)

http://wiki.Apache.org/couchdb/Document_Update_Handlers

CouchDB(0.10以降)は、インプレース更新をサポートするようになりました。私はそれがどのように機能するか理解するのに苦労しています。提供されている例を使用しようとしましたが、機能させることができませんでした。

インプレース更新にアクセスするために使用されるいくつかの例とURIを誰かが提供できますか?.

ありがとう

31
Jason

サンプル関数in-placeは、他のデータベースの「インプレース」更新と同じではありません。 CouchDBは引き続き追加専用アーキテクチャを使用します。ドキュメント更新ハンドラーは、新しいドキュメントリビジョンなどを作成します。

それでも、更新ハンドラーは非常に便利で、学ぶ価値があります。

アキュムレータを備えたドキュメントがあるとします。 amountパラメータを使用して増分量を指定し、HTTPクエリを1つだけ使用してドキュメントに整数を累積したいとします。次のコマンドを検討してください。

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

(POSTのJSONオブジェクトの後に、ファイルの終わり^ Dを押すことを忘れないでください。)

次に、ドキュメントの蓄積を確認します(my_doc)存在します:

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

これで、accumulateパラメーターを指定してamount更新ハンドラーを呼び出して、フィールドを更新できます。

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}

新しいnumber値が38、値23 +15であることに注意してください。

49
JasonSmith

上記の例で遊んだときに非常に便利だと思ったものがあります。更新ハンドラーをインストールしたら、それを使用して更新ハンドラー自体を更新できます。たとえば、更新ハンドラーがupdate.jsonにある場合、次のように実行できます。

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

update.jsonに含まれるもの:

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

注目すべき点がいくつかあります。ステートメントvar resp = eval(uneval(doc)) clones doc。もっとあります ここにクローン作成に関する情報 。 __revisions_フィールドは大きくなる可能性があるため、応答で削除することは私のユースケースにとって意味があります。 toJSON(resp)を使用すると、応答が文字列として返されますが、正常な応答での__rev_の値は間違っています。正常に更新された正しいリビジョンを取得するには、応答ヘッダーの_X-Couch-Update-NewRev_を確認してください。更新が成功せず、競合が発生する可能性があります ここで説明

4
Ram Rajamony