2012-03-30 10 views
1

イベントjsonオブジェクトのリストを保存または更新する次の方法があります。私はcouchdbの一括create_or_update関数を見つけることができなかった、私は各オブジェクトを照会し、それがデータベースに存在し、それに応じて作成/更新しなければならなかった。残念ながら、これは非常に非効率的で、1725イベントが処理されるには6分かかります。誰かがより良いデザインを提案できますか?それは数秒で完了しなければならない。私のcouchdbは実際にはsslクラウドデータベースであり、私のアプリは、クラウドと実際に組み合わせられているheroku上のアプリよりも、Heroku上でホストされています。Rubyを使用したCouchDbのバルクupdate_or_createの最適化

def self.store(bulk, resource) 
      JSON::Validator.validate!(SCHEMA, bulk, :list => true) 
      bulk.each{ |event| 
       response = resource.get("/database-dev/_design/Event/_view/byEID?key=\"#{event['eid']}\"") 
       if (response["rows"].nil? || response["rows"].empty?) then 
        o = [('a'..'z'),('A'..'Z'),(0..9)].map{|i| i.to_a}.flatten 
        o.push('-','_') 
        event['_id'] = (0..50).map{ o[rand(o.length)] }.join 
        event['resource'] = 'Event' 
        resource.post('/database-dev', event.to_json) 
       else 
        resource.put("/database-dev/#{response['rows'][0]['id']}", event.to_json) 
       end 
      } 
     end 

答えて

1

CouchDB bulk document APIを使用して、作成または更新することができます。もちろん、あなたが_revの値を持つ「飛行ブラインド」であるため、改訂の競合を引き起こす可能性があるというトレードオフがあります。それはあなたにとって問題ではないかもしれませんし、場合によっては、あなたのアプリケーションに応じて、それは不可能または極端に稀であるかもしれません。 POST本体に"all_or_nothing":trueオプションを追加するだけです。

また、2回の往復でバルク作成または更新を行うこともできます。最初にすべてのドキュメントのリビジョンを取得し、_bulk_docsの伝言をすべて_revの値を設定して投稿します。

POST /database-dev/_all_docs 
Content-Type: application/json 

{"keys": ["id_1", "id_2", "bad_id"]} 

HTTP/1.1 200 OK 
...couch headers... 

{"total_rows":10,"offset":0,"rows":[ 
    {"id":"id_1","key":"id_1","value":{"rev":"1-6919deb28bdb1d4cf5b53188be5683be"}}, 
    {"id":"id_2","key":"id_2","value":{"rev":"1-37bb8117bc6c7b182ca26aae16717408"}}, 
    {"key":"bad_id", "error":"not_found"} 
]} 

(ビューを要求するときは、同じことを行うことができます。)

今、あなたは_revのすべての値が_bulk_docsに送信するために知っています。 ("rev"の値がある場合はそれを使用し、それ以外の場合は_revを残して新しい文書を作成してください)

関連する問題