2011-05-08 50 views
2

我有2個大的CSV文件與數百萬行。 由於這2個CSV來自MySQL,我想將這兩個表合併到沙發DB中的一個Document中。替代防止重複導入CSV到CouchDB

什麼是最有效的方法來做到這一點?

我目前的方法是:

  1. 導入CSV一號
  2. 進口第二CSV

爲了避免重複,該程序將搜索的文檔與每一行的關鍵。找到該行後,然後使用來自第二個CSV的列更新文檔。問題是,搜索每一行真的需要很長時間。導入第二個CSV時,它更新了30個文檔/秒,我有大約700萬行。粗略計算,完成整個導入大約需要64小時。

謝謝

+0

我不完全明白這裏的用例。你談論將兩個表合併成一個文件,是嗎?在它的最後,你只需要在數據庫中有一個巨大的文檔?如果你只是想檢查重複,我認爲有一個更簡單的解決方案。 – 2011-05-08 17:15:47

回答

2

另一種選擇是簡單地做你現在正在做的事情,但使用批量文檔API來提高性能。

對於每批文稿:

  1. POST到/db/_all_docs?include_docs=true與這樣的身體:

    { "keys": [ "some_id_1" 
          , "some_id_2" 
          , "some_id_3" 
          ] 
    } 
    
  2. 取決於你得到的結果建立你的_bulk_docs更新。

    • 文件已經存在,則必須更新:{"key":"some_id_1", "doc": {"existing":"data"}}
    • 文件不存在,則必須創建它:{"key":"some_id_2", "error":"not_found"}
  3. POST到/db/_bulk_docs有這樣的身體:

    { "docs": [ { "_id": "some_id_1" 
          , "_rev": "the _rev from the previous query" 
          , "existing": "data" 
          , "perhaps": "some more data I merged in" 
          } 
          , { "_id": "some_id_2" 
          , "brand": "new data, since this is the first doc creation" 
          } 
          ] 
    } 
    
2

這聽起來像你有一個「主鍵」您從一行知道(或者你可以從該行計算的話)。這是文件_id的理想選擇。

問題是,如果您嘗試添加第二個CSV數據,但是已經有一個文檔與_id相同,則會得到409 Conflict。那是對的嗎? (如果是的話,請糾正我,所以我可以解決問題的答案。)

我覺得這是對你一個很好的答案:

使用_bulk_docs導入的一切,然後修復衝突。

從一個乾淨的數據庫開始。

使用Bulk docuent API可以根據HTTP查詢插入儘可能多的來自第一個然後第二個CSV集—的所有行,例如,每次1,000個。 (批量文檔是不是插入一個接一個快得多。)

始終_bulk_docs POST數據添加"all_or_nothing": true。這將保證每次插入都會成功(假設沒有電力損失或全高清等災難)。

當你完成後,一些文件將是衝突,這意味着你插入兩次相同的_id值。這沒有問題。只需按照此步驟合併兩個版本:

  1. 對於有衝突各_id,通過GET /db/the_doc_id?conflicts=true從沙發上獲取它。
  2. 將衝突版本中的所有值合併到文檔的新最終版本中。
  3. 將最終的合併文檔提交到CouchDB並刪除衝突的修訂。請參閱conflict resolution上的CouchDB權威指南部分。 (您也可以使用_bulk_docs來加快速度。)

希望這將澄清了一下。請注意,我從http://github.com/iriscouch/manage_couchdb安裝了* manage_couchdb * couchapp。它有一個簡單的視圖來顯示衝突。

$ curl -XPUT -Hcontent-type:application/json localhost:5984/db 
{"ok":true} 

$ curl -XPOST -Hcontent-type:application/json localhost:5984/db/_bulk_docs --data-binary @- 
{ "all_or_nothing": true 
, "docs": [ { "_id": "some_id" 
      , "first_value": "This is the first value" 
      } 
      , { "_id": "some_id" 
      , "second_value": "The second value is here" 
      } 
      ] 
} 
[{"id":"some_id","rev":"1-d1b74e67eee657f42e27614613936993"},{"id":"some_id","rev":"1-d1b74e67eee657f42e27614613936993"}] 

$ curl localhost:5984/db/_design/couchdb/_view/conflicts?reduce=false\&include_docs=true 
{"total_rows":2,"offset":0,"rows":[ 
{"id":"some_id","key":["some_id","1-0cb8fd1fd7801b94bcd2f365ce4812ba"],"value":{"_id":"some_id","_rev":"1-0cb8fd1fd7801b94bcd2f365ce4812ba"},"doc":{"_id":"some_id","_rev":"1-0cb8fd1fd7801b94bcd2f365ce4812ba","first_value":"This is the first value"}}, 
{"id":"some_id","key":["some_id","1-d1b74e67eee657f42e27614613936993"],"value":{"_id":"some_id","_rev":"1-d1b74e67eee657f42e27614613936993"},"doc":{"_id":"some_id","_rev":"1-d1b74e67eee657f42e27614613936993","second_value":"The second value is here"}} 
]} 

$ curl -XPOST -Hcontent-type:application/json localhost:5984/db/_bulk_docs --data-binary @- 
{ "all_or_nothing": true 
, "docs": [ { "_id": "some_id" 
      , "_rev": "1-0cb8fd1fd7801b94bcd2f365ce4812ba" 
      , "first_value": "This is the first value" 
      , "second_value": "The second value is here" 
      } 
      , { "_id": "some_id" 
      , "_rev": "1-d1b74e67eee657f42e27614613936993" 
      , "_deleted": true 
      } 
      ] 
} 
[{"id":"some_id","rev":"2-df5b9dc55e40805d7f74d1675af29c1a"},{"id":"some_id","rev":"2-123aab97613f9b621e154c1d5aa1371b"}] 

$ curl localhost:5984/db/_design/couchdb/_view/conflicts?reduce=false\&include_docs=true 
{"total_rows":0,"offset":0,"rows":[]} 

$ curl localhost:5984/db/some_id?conflicts=true\&include_docs=true 
{"_id":"some_id","_rev":"2-df5b9dc55e40805d7f74d1675af29c1a","first_value":"This is the first value","second_value":"The second value is here"} 

最後兩個命令顯示沒有衝突,並且「合併」文檔現在用作「some_id」。