如何保存CouchDB / Cloudant中的更改,以便以后对我的数据库甚至特定文档进行时间点恢复?
答案 0 :(得分:1)
我们正在努力使其成为一流的功能,但在我们推出之前,我们的客户就是这样做的:
您拥有集合,并在这些集合中拥有资源。因此,您保留一个日志记录数据库,其中每个文档都具有collection-resource
之类的ID,因此对于名为“cars”的集合和名为“Ford”的资源,您的日志记录数据库中将有一个名为{{1的文档}}。该文件如下:
cars-ford
每次触摸或修改资源时,您的应用程序都会通过将新版本附加到{
versions: [...]
}
字段的末尾来更新日志记录文档。该版本可能如下所示:
versions
我们将使用该视图返回所有文档的所有版本的列表,并按每次更改的时间排序。
然后,这是你如何使用它来进行恢复等等:
获取最新版本的资源
完整获取文档,并抓取{
timestamp: '...', # some integer timestamp, for sorting
doc: {...} # attributes of the document as of the save
}
字段中的最后一个元素。这是最新的版本。
查看与时间戳相关的所有版本
我们将创建一个按时间戳排序的视图。视图如下所示:
versions
假设我们的数据库名为{
map: "function(doc) {
for(var i in doc.versions){
emit(doc.versions[i].timestamp, doc.versions[i].doc);
}
}"
}
,我们的视图所在的设计文档名为loggy
,视图本身名为restore
。然后我们将对此网址发出GET请求:
time
... {CLOUDANT_HOST}/loggy/_design/restore/_view/time?startkey='...'
的值是某个时间戳。未经修改的,将在指定的时间戳之后返回每个版本。添加startkey
,您将在时间戳之后获得X版本。添加limit=X
,您将获得时间戳之前的版本,而不是之后的版本。
请参阅资源的第N个版本
如上所述,但我们稍微调整一下我们的观点:
descending=true
现在我们的视图结果是通过索引而不是时间戳来键入的。因此,我们只是将N传递给第N个版本周围的版本,而不是将时间戳传递给{
map: "function(doc){
for(var i in doc.versions){
emit(i, doc.versions[i].doc);
}
}"
}
。
获取集合或资源的修订数
我们将使用另一个视图按集合和资源进行分组:
startkey
使用查询参数{
map: "function(doc){
// split te ID into collection and resource
var parts = doc._id.split('-');
// emit them as keys so we can group by them
emit([doc.parts[0], doc.parts[1]], null);
}",
reduce: "_count"
}
和group
按键对结果进行分组。因此,如果我们想要在group_level
集合中触及资源的事件数量,我们将使用这样的查询字符串:
cars
?group=true&group_level=1&key="cars"
对其键相同的结果进行分组,但group
表示“只有第一个键上的组”,在我们的示例中是集合。 group_level=1
指定仅返回其键与给定值匹配的文档。
获取指定馆藏的所有资源
使用_all_docs视图,我们将使用如下的查询字符串:
key
还记得我们功能的?reduce=false&startkey="{collection}-"&endkey="{collection}0"
部分吗? reduce
值表示“返回_count
发出的记录数”。 map
表示“不要那样做”。相反,只运行reduce=false
函数。
map
和startkey
对使用Cloudant如何对结果进行排序,以排除除了与给定集合开头的ID匹配的值之外的所有内容。
更新文档
获得要恢复的版本后,获取当前版本的资源,从loggy数据库获取过去的版本,并使用当前版本的{{1}将过去的版本PUT到资源价值。巴姆,恢复了。冲洗并重复以进行时间点恢复。