【问题标题】:CouchDB view reduce one doc per keyCouchDB 视图每个键减少一个文档
【发布时间】:2020-05-31 19:58:10
【问题描述】:

我正在尝试使用 couchDb 视图解决看似相当简单的问题,但我的结果集甚至没有接近目标。

我不是更新文档,而是每次都创建一个新文档作为我的版本控制策略,并将这些文档与一个名为 ver 的版本控制字段绑定在一起。版本链中的第一个文档将看到 ver 字段和 _id 字段具有相同的值。链中的所有后续文档将具有与链中先前文档相同的 ver 字段,但将具有唯一的 _id 字段。这些文档还有一个createdTime 字段,这是我知道哪个文档是最新的方式。

这是我的文件:

{
  "_id": "abcd-1234-efgh-9876",
  "ver": "abcd-1234-efgh-9876",
  "createdTime": "2020-01-12 01:15:00 PM -0600",
  ...
},
{
  "_id": "uopa-3849-pmdi-1935",
  "ver": "abcd-1234-efgh-9876",
  "createdTime": "2020-02-16 02:39:00 PM -0600",
  ...
}

这是我的地图功能:

function (doc) {
  emit(doc.ver, doc);
}

这是我的 reduce 函数:

function(keys, values, rereduce) {
    var latestVersions = {};

    for (var i = 0; i < keys.length; i++) {
      var found = latestVersions[keys[i][0]];
      if (!found || found.createdTime < values[i].createdTime) {
        latestVersions[keys[i][0]] = values[i];
      } 
    }

    return latestVersions;
}

最后,这是我想要的视图输出(只是我想要的文档):

{
  "_id": "uopa-3849-pmdi-1935",
  "ver": "abcd-1234-efgh-9876",
  "createdTime": "2020-02-16 02:39:00 PM -0600",
  ...
}

我在这里缺少什么? reduce 函数返回两条记录,这不是我想要的。我正在努力实现的目标是可能的,还是有更好的方法来解决这个问题?

更新

当使用单个键访问视图时,我能够让它工作,这是我的用例之一。

function (keys, values, rereduce) {
  var toReturn = values[0];
    for (var i = 1; i < values.length; i++) {
      if (values[i].createdTime > toReturn.createdTime) {
        toReturn = values[i];
      }
    }

    return toReturn;
}

但是,我还有另一个用例将返回视图中的所有数据。所需的结果与上面相同,但我用于单个键的函数将只返回一个结果。如何使用共享键过滤多个值,例如 1 个“共享”键:n 值 -> 1 个键:1 值。

【问题讨论】:

    标签: mapreduce couchdb document-versioning


    【解决方案1】:

    当我偶然发现这个couchbase article 时,我终于能够解决这个问题。它比其他一些枯燥的计算机科学文档清晰得多。

    我仍然不明白为什么某些项目在 reduce 方法中分组,而其他项目则没有。例如,对于共享相同键的 6 个项目,reduce 被调用了 5 次;只有一个键实际上对任何内容进行了分组——两个文档的数组。这可能与我掩饰的那些枯燥的计算机科学 B 树文档有关。

    无论如何,我能够确定我需要做的就是在这两种情况下按ver 字段对值进行分组(唯一的区别是 rereduce 有一个二维数组)。这是我的 reduce 函数最终的样子:

    function (keys, values, rereduce) {
    
      var toValues = function(myMap) {
        return Object.keys(myMap).map(function(key) {
          return myMap[key];
        });
      }
    
      if (rereduce) {
        // values should look like [[{...}, {...}], [{...}]]
        var outputMap = {};
    
        for (var i = 0; i < values.length; i++) {
          for (var j = 0; j < values[i].length; j++) {
            var currentEl = values[i][j];
            var found = outputMap[currentEl.ver];
    
            if ((found && found.createdDate < currentEl.createdDate) || !found) {
                outputMap[currentEl.ver] = currentEl;
            }
          }
        }
    
        return toValues(outputMap);
      } else {
        var outputMap = {};
    
        for (var i = 0; i < values.length; i++) {
          var found = outputMap[values[i].ver];
    
          if ((found && found.createdDate < values[i].createdDate) || !found) {
              outputMap[values[i].ver] = values[i];
          }
    
        }
    
        return toValues(outputMap);
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2011-01-20
      • 2012-10-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多