防止将CSV导入CouchDB时重复的替代方法



我有 2 个包含数百万行的大 CSV 文件。因为这两个 CSV 来自 MySQL,所以我想将这两个表合并到沙发数据库中的一个文档中。

最有效的

方法是什么?

我目前的方法是:

  1. 导入第一个 CSV
  2. 导入第二个 CSV

为了防止重复,程序将使用每一行的键搜索文档。 找到该行后,将使用第二个 CSV 中的列更新文档

问题是,搜索每一行确实需要很长时间。在导入第二个 CSV 时,它每秒更新 30 个文档,我有大约 700 万行。粗略计算,完成整个导入大约需要64小时。

谢谢

听起来你有一个从行中知道的"主键"(或者你可以从行中计算它)。这是理想的,因为文档_id

问题是,如果您尝试添加第二个CSV数据,但已经有一个具有相同_id的文档,则会409 Conflict。这是对的吗?(如果是这样,请纠正我,以便我修复答案。

我认为有一个很好的答案给你:

使用_bulk_docs导入所有内容,然后修复冲突。

从干净的数据库开始。

使用批量文档 API 插入第一个和第二个 CSV 集中的所有行 - 每个 HTTP 查询尽可能多地插入,例如一次插入 1,000 行。(批量文档比逐个插入要快得多。

始终_bulk_docs POST 数据中添加"all_or_nothing": true。这将保证每次插入都会成功(假设没有断电或全高清等灾难)。

完成后,某些文档将发生冲突,这意味着您为相同的_id值插入了两次。这没问题。只需按照以下过程合并两个版本:

  1. 对于每个有冲突的_id,请按GET /db/the_doc_id?conflicts=true从沙发上取下它。
  2. 冲突版本中的所有值合并到文档的新最终版本中。
  3. 将最终合并的文档提交到 CouchDB 中,并删除冲突的修订。请参阅 CouchDB 权威指南中有关冲突解决的部分。(您也可以使用_bulk_docs来加快速度。

希望这会澄清一点。请注意,我从 http://github.com/iriscouch/manage_couchdb 安装了 *manage_couchdb* 沙发应用程序。它有一个简单的视图来显示冲突。

$ 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"。

另一种选择是简单地执行您正在执行的操作,但使用批量文档 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"
                }
              ]
    }
    

最新更新