2012-03-30 3 views
1

У меня есть следующий метод, который хранит или обновляет список объектов json события. Я не мог найти большую функцию create_or_update для couchdb, мне приходилось запрашивать каждый объект и посмотреть, существует ли он в базе данных и соответствующим образом создавать/обновлять. К сожалению, это крайне неэффективно, для обработки 1725 событий требуется 6 минут. Может ли кто-нибудь предложить лучший дизайн? Это нужно сделать через пару секунд. Мой couchdb на самом деле является облачной базой данных ssl, а мое приложение размещено на Heroku, которое отличается от приложения на heroku, которое фактически сочетается с облачным.Массовая оптимизация update_or_create в CouchDb с Ruby

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, компромисс заключается в том, что вы можете создавать конфликты версий. Для вас это не проблема, или в некоторых случаях это может быть невозможно или крайне редко (в зависимости от вашего приложения). Просто добавьте опцию "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 для создания нового документа.)

Смежные вопросы