我从来没有做过这样的事情,但我想我知道该怎么做。您可以做的是对评级进行快照并在每个页面中引用它。您可能希望您的视图不占用太多空间,因此您不应该映射文档的单独副本,其中在拍摄快照后投票未更改。因此,您可以执行以下操作:
- 在您的文档中添加一些带有时间戳的评级历史记录。
- 像这样映射评级和历史。
- 在您的应用程序中获取当前时间:
start_time = Date.now()
并查询所有页面。
- 清理比最旧的活动会话更早的历史记录。
问题是,如果您发出[votes, date]
并尝试分页,您将永远不知道必须获取多少文档才能获得每页所需的数量。总有一些旧版本你必须跳过,你将不得不从 DB 获取下一个版本。这就是为什么你可以考虑发出: [date, votes]
,总是读取视图两次——对于start_time
当前时间,然后合并和排序结果(就像在合并排序中一样)。
广告 1:
{ ...,
votes: 12,
history: [
{date: 1357390271342, votes: 10},
{date: 1357390294682, votes: 11}
]
}
广告 2:
function (doc) {
emit([{}, doc.votes], null);
doc.history && doc.history.forEach(function(h) {
emit([h.date, h.votes], null);
});
}
广告 3:
?startkey=[start_time, votes]&limit=items_per_page_plus1
?startkey=[{}, votes]&limit=items_per_page_plus1
合并列表,votes
在您的应用程序中排序(在列表功能中)。如果您在使用时遇到问题,start_docid
那么您可以使用 ID 显式发出[date, votes, id]
和查询。即使这个特定的文档更改了votes
它,它仍然会在历史记录中可用。
Ad.4:如果您发出[date, votes]
,那么您可以获得过时的历史宽度:?startkey=[0]&endkey=[oldest_active_session_time]&inclusive_end=false
并使用更新处理程序更新它们:
function(doc, req) {
if (!doc || !doc.history) return [null, 'Error'];
var history = new Array();
var oldest = +(req.query.date);
doc.history.forEach(function(h) {
if (h.date >= oldest)
history.push(h);
});
doc.history = history;
return [doc, 'OK'];
}
注意:我没有测试过,所以如果不修改,预计不会运行:)
据我所知,CouchDB 使用 b-tree 阴影进行更新,原则上应该可以访问旧版本的视图。我不喜欢 CouchDB 设计,所以这只是一个猜测,似乎没有任何(记录在案的)API。