2

我必须更改我的一个 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 通信。

4

1 回答 1

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 个要转换的文档,请 GET /my_db/_design/converter/_view/to_do?limit=50。每行的"value"字段将是文档的完整副本,因此您可以立即通过转换器功能运行它。

转换文档后,您可以将其 POST 回数据库,或者建立一个批处理并使用它_bulk_docs来执行相同的操作。(批量文档也是一样的,只是要快一点。)随着每个文档的存储,它会从to_do视图中消失。(如果你得到一个409 Conflict错误,忽略它。)重新运行这个过程,直到有 0 行to_do,你就完成了!

你可以从你的情况判断你需要多小心。如果这是生产数据,你最好写好单元测试!如果是开发环境,那就去吧!

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

于 2012-01-11T10:49:28.030 回答