我必须更改包含某个字段的某个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进行通信。
答案 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行并且您已完成!
您可以根据自己的情况判断自己需要多么谨慎。如果这是生产数据,那么最好编写好的单元测试!如果它是一个开发环境,那就去吧!
最后一招是创建一个新的空数据库并将主数据库复制到它。现在您有一个重复的沙箱来尝试您的想法。您可以删除并重新复制沙箱,直到您对结果感到满意为止。