我有以下方法来存储或更新事件json对象列表。我找不到couchdb的批量create_or_update函数,我不得不查询每个对象,看它是否存在于数据库中并相应地创建/更新。不幸的是,这是非常低效的,需要6分钟才能处理1725个事件。有人可以提出更好的设计吗?它必须在几秒钟内完成。我的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
答案 0 :(得分:1)
您可以使用CouchDB bulk document API创建或更新。当然,由于您使用_rev
值“盲目”,所以权衡是您可能会创建修订冲突。这对您来说可能不是问题,或者在某些情况下可能不可能或非常罕见(取决于您的应用)。只需在POST正文中添加"all_or_nothing":true
选项即可。
或者,您可以在两次往返中进行批量创建或更新。首先获取所有文档修订,然后发布传统的_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"}
]}
(您可以在请求视图时执行相同的操作。)
现在您知道要在_bulk_docs中发送的_rev
的所有值。 (如果它具有"rev"
值,请使用该值,否则,请将_rev
保留为创建新文档。)