如何编写基于时间戳的 map/reduce 视图以避免 CouchDB 中的更新?

How can I write a timestamp-based map/reduce view to avoid updates in CouchDB?

我正在尝试 "avoid updates" 在 CouchDB 中,这似乎是推荐的。 但是我无法使 "reduce" 视图 returns 只有最新值。在下面的数据集中,文档 a8f2298e5961b0ebf60e56022d253d2b(其中 s=FooQuux)基本上应该永远不会返回,并且可以作为 "cleanup" 操作删除而不会影响。

我希望能够进行如下操作:

对于最后两个,考虑到限制,我不确定是否可以编写一个 map/reduce 视图来同时执行这两项操作。


数据:(这是一个人为的例子)

给定数据:(其中 t 是时间戳,u 是用户名,s 是字符串)

数据库:

{
  "_id": "_design/all",
  "views": {
    "s": {
      "map": "function(doc) { if(doc.u) { emit([doc.u, doc.s, doc.t], doc.s); } }"
    },
    "slen": {
      "map": "function(doc) { if(doc.u) { emit([doc.u, doc.s, doc.t], doc.s.length); } }",
      "reduce": "_sum"
    }
  },
  "language": "javascript"
}

{
  "_id": "a8f2298e5961b0ebf60e56022d251ebd",
  "t": 2,
  "u": "b",
  "s": "Quux"
}

{
  "_id": "a8f2298e5961b0ebf60e56022d253a1b",
  "t": 1,
  "u": "a",
  "s": "Bar"
}

{
  "_id": "a8f2298e5961b0ebf60e56022d253d2b",
  "t": 0,
  "u": "a",
  "s": "FooQuux"
}

通过像这样创建一个 Map 函数:

function(doc) { emit([doc.u, doc.t], doc.s); }

您可以通过两种方式使用视图:

  • 聚合数据 - 获取 u 值的文档数量计数(使用 _count reducer 和 ?group_level=1
  • 到 select 值为 u - (reduce=false&endkey=["a"]&startkey=["az"]&descending=true&limit1)
  • 的最新记录

由于在索引过程中文档是单独处理的,因此不可能执行需要您了解另一个文档内容的逻辑。也就是说,您可以阻止文档在索引时被索引,if(doc.live){ emit(doc.u,null)} 但您不能执行 "cross-document" 逻辑。

不想pull a LEGO但这里有一个可能的解决方案:

地图

每个@Glynn-Bird 在

function(doc) {
  emit([doc.u, doc.t], doc.s);
}

减少

function(keys, values, rereduce){
  function rollin(map, u, o) {
    if((!map[u]) || (o.t > map[u].t)) {
        return o;
    } else {
        return map[u];
    }
    return map;
  }
  var m = {};
  for(var i=0;i<values.length;i++) {
      var v = values[i];
      if(rereduce) {
          // merge in this chunk
          for(var u in v) {
            m[u] = rollin(m, u, v[u]);
          }
      } else {
          // roll in single entries
          m[keys[i][0][0]] = rollin(m, keys[i][0][0], {
              s: v,
              t: keys[i][0][1],
          });
      }
  }
  return m;
}

输出

reduce=false,startkey["a",{}]endkey["a"],降序,limit 1

这是给"selecting a single specified entry"

{
  "value": "Bar",
  "key": [
    "a",
    1
  ],
  "id": "a8f2298e5961b0ebf60e56022d253a1b"
}

减少,组级别 1

这是用于列表"specific values"(通过查询选择)

{
  "value": {
    "b": {
      "s": "Quux",
      "t": 2
    }
  },
  "key": [
    "b"
  ]
}

{
  "value": {
    "a": {
      "s": "Bar",
      "t": 1
    }
  },
  "key": [
    "a"
  ]
}

减少,组级别None

这是为了倾倒所有物品。

{
  "value": {
    "a": {
      "s": "Bar",
      "t": 1
    },
    "b": {
      "s": "Quux",
      "t": 2
    }
  },
  "key": null
}