1

我有以下存储或更新事件 json 对象列表的方法。我找不到 couchdb 的批量 create_or_update 函数,我必须查询每个对象并查看它是否存在于数据库中并相应地创建/更新。不幸的是,这是非常低效的,处理 1725 个事件需要 6 分钟。有人可以提出更好的设计吗?它必须在几秒钟内完成。我的 couchdb 实际上是一个 ssl cloudant 数据库,我的应用程序托管在 Heroku 上,这与 heroku 上实际与 cloudant 结合的应用程序不同。

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 
4

1 回答 1

1

您可以使用CouchDB 批量文档 API来创建或更新。当然,由于您对这些值“视而不见” _rev,因此权衡是您可能会产生修订冲突。这对您来说可能不是问题,或者在某些情况下它可能是不可能的或极其罕见的(取决于您的应用程序)。只需"all_or_nothing":true在您的 POST 正文中添加选项。

或者,您可以在两次往返中进行批量创建或更新。首先获取所有文档修订版,然后发布一个设置了所有值的传统_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省略以创建一个新文档。)

于 2012-04-10T09:33:13.003 回答