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

时间:2016-08-23 02:00:00

标签: mapreduce couchdb cloudant

我正在努力避免更新"在CouchDB中,似乎是推荐。 但是我能够做出一个"减少"仅返回最新值的视图。在下面的数据集中,文档a8f2298e5961b0ebf60e56022d253d2b(其中s = FooQuux)基本上不应该被返回,并且可以作为"清理"删除。没有影响的运作。

我希望能够执行以下操作:

  • 检索a ==>的值Bar
    • this technique可以使用s视图,搜索限制= 1的[["a"], ["a",{}]]
  • 检索所有值==> a=Bar, b=Quux
    • 我可以写一个减少到"去掉"具有较旧时间戳的文档?

对于最后两个,我不确定在给定约束的情况下是否可以编写一个可以同时执行这两个操作的map / reduce视图。

  • 获取每个用户的字符串长度 - group = 1 == a=3, b=4(不计算FooQuux)
  • 获取所有用户的字符串长度 - group = None == 7(不计算FooQuux)

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

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

  • 在时间戳0,用户a设置值FooQuux
  • 在时间戳1,用户a设置值Bar
  • 在时间戳2,用户b设置值Quux

数据库:

{
  "_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"
}

2 个答案:

答案 0 :(得分:3)

通过创建这样的Map函数:

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

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

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

由于在索引编制过程中单独处理文档,因此无法执行需要您了解其他文档内容的逻辑。即,您可以阻止文档在索引时{,1}}编制索引,但不能执行“跨文档”逻辑。

答案 1 :(得分:0)

没有尝试pull a LEGO,但这是一个可能的解决方案:

地图

https://stackoverflow.com/a/39128241/185799

中的@ 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"],降序,限制1

这是为了“选择一个指定的条目”

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

减少,第1组

这是用于列出“特定值”(由查询选择)

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

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

减少,组级无

这是为了倾销所有物品。

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