如何更改CouchDB数据库中所有文档的结构?

时间:2012-01-11 09:19:06

标签: java couchdb ektorp

我必须更改包含某个字段的某个CouchDB数据库中所有现有文档的结构。 现在,该字段只是一个简单的字符串,例如:

{
  // some other fields
  "parameters": {
     "typeId": "something",
     "otherField": "dont_care"
  }
}

在这个例子中,我感兴趣的字段是“typeId”。 我想让它成为一个字符串数组,因为对此的要求被修改:( 但我显然需要在所有文档中保留该字段的当前值!因此,从上面的例子中,结果将是:

{
  // some other fields
  "parameters": {
     "typeId": [ "something" ] // now we can have more items here
     "otherField": "dont_care"
  }
}

任何想法如何实现这一目标?

以防这有助于:我的Java Web应用程序通过Ektorp库与CouchDB进行通信。

1 个答案:

答案 0 :(得分:2)

我想首先编写一个函数(或方法或类),将旧式文档转换为新式文档,并在必要时正确处理不相关的文档(如设计文档)。编写一些单元测试,直到您对此代码有信心。

下一步基本上是一个循环,用于查找旧式文档并使用您的修改例程将它们更新为新式文档。

如果您拥有较小的数据集,则只需查询/_all_docs?include_docs=true即可在一批中处理整个数据集。如果你有一个更大的数据集,也许写一个将识别旧式文档的视图

function(doc) {
  // map function for "to_do" view
  if(doc.parameters && typeof doc.parameters == "string")
    emit(doc._id, doc)
}

此视图将显示要执行的所有旧式文档。要获取另外50个要转换的文档,请获取/my_db/_design/converter/_view/to_do?limit=50。每行的"value"字段都是文档的完整副本,因此您可以立即通过转换器函数运行它。

转换文档后,您可以将其发回数据库,也可以构建批处理并使用_bulk_docs执行相同操作。 (批量文档是相同的,只是更快一点。)随着每个文档的存储,它将从to_do视图中消失。 (如果出现409 Conflict错误,请忽略它。)重新运行此过程,直到to_do中有0行并且您已完成!

您可以根据自己的情况判断自己需要多么谨慎。如果这是生产数据,那么最好编写好的单元测试!如果它是一个开发环境,那就去吧!

最后一招是创建一个新的空数据库并将主数据库复制到它。现在您有一个重复的沙箱来尝试您的想法。您可以删除并重新复制沙箱,直到您对结果感到满意为止。