在MapReduce实现中,reduce函数是否与map函数类似地索引?

时间:2017-01-31 06:59:43

标签: view mapreduce couchdb

如果我在Couch中有几个文档看起来像这样:

{
   "_id": "be890e3ee1457e920f12722c44001b0e", // Or whatever auto ID
   "_rev": "7-74d1787aa3ca6d2526c4436577da660f", // Or whatever auto rev
   "type_": "count",
   "value": -1,
   "time": 1485759832925 // This is an Epoch time, the result of this JavaScript: var x = (new Date()).getTime(), that I calculate in the console just before saving the doc
}

然后我创建了一个map函数来检索这些文档(我在创建一些文档后直接运行):

function(doc) {
    if (doc.type_) {
        if (doc.time) {
            var datetime = (new Date()).getTime();
            var docTime = doc.time;
            var docAge = datetime - docTime;
            // Only emit docs younger than 1 minute
            if (docAge / 1000 <= 60) {
                emit(doc.time, docAge);
            };
        };
    };
};

我发现,一旦计算了视图,docAge将永远不会改变,并且尽管文件过于陈旧,也会始终发出文档。

如果你打开一个doc并重新保存它,那么视图就不会发出那个doc(因为它反映为CouchDB更新,现在时间值太旧了),但其他文档不会被重新计算(即这些文档的docAge仍然是相同的。)

因此,我可以看到视图会逐步更新以反映更改的文档。据我了解,它们是缓存的。

问题:

  1. 这些缓存的视图存储在哪里?
  2. 每次映射时都会重新计算Group和reduce输出 功能逐步更新?

1 个答案:

答案 0 :(得分:1)

您的观点本身并未“缓存”。 CouchDB观点背后的想法是它们是确定性的,因此不应受到有关文档之外的任何事物的影响。

在视图中使用new Date()意味着您引入了一个外部资源(时钟),这意味着您的视图索引将以您不打算根据您的问题计算。

您的地图函数必须处理绝对值,因此无论重建视图索引的时间如何,它都应输出时间戳。在您的应用程序中,您将把要查询的时间作为参数传递给视图查询。

例如,请考虑此视图功能:

function (doc) {
  if (doc.type_ && doc.time) {
    emit(doc.time);
  }
}

它将输出所有文件的时间。然后,您将查询在预期时间范围内传递的视图。

?start_key=<timestamp from 1 minute ago>

然后你会得到时间戳在最后一分钟的文件。您可以包含end_key来指定上限。

CouchDB中的MapReduce视图如何设计可以解决一些心理障碍,因此我强烈建议他们Guide to Views开始使用。 (事实上​​,他们最新的文档非常好,我强烈建议阅读所有文档)