RethinkDB - 如何 return 对分组数据进行滑动 window

RethinkDB - How to return a sliding window on grouped data

我有一些对象:

[
  { 'time': 1, 'data': { '1': 10, '2': 100} },
  { 'time': 2, 'data': { '1': 20, '2': 100} },
  { 'time': 3, 'data': { '1': 30, '2': 200} },
  { 'time': 4, 'data': { '1': 40, '2': 100} },
  { 'time': 5, 'data': { '1': 50, '2': 300} },
  { 'time': 6, 'data': { '1': 60, '2': 200} }
]

和两个变量widthoverlap:

假设 width = 3overlap = 2。有什么办法可以得到关注吗?

[ { 'key': '1',
    'rows': [ { 'time': 1, 'values': [10,20,30] },
              { 'time': 2, 'values': [20,30,40] },
              { 'time': 3, 'values': [30,40,50] },
              { 'time': 4, 'values': [40,50,60] }
            ]
  },
  { 'key': '2',
    'rows': [ { 'time': 1, 'values': [100,100,200] },
              { 'time': 2, 'values': [100,200,100] },
              { 'time': 3, 'values': [200,100,300] },
              { 'time': 4, 'values': [100,300,200] }
            ]
  } ]

到目前为止我已经设法得到这个:

[ { 'key': '1',
    'row': { 'time': 1, 'values': [10,20,30,40,50,60] }
  },
  { 'key': '2',
    'row': { 'time': 1, 'values': [100,100,200,100,300,200] }
  } ]

使用这个:

.concatMap(function(item) {
  return item('data').keys().map(function(key) {
    return {
      'key': key,
      'row': { 
        'time': item('time'),
        'values': [item('data')(key)]
      }
    }
  })
})
.group('key')
.ungroup()
.map(function(list) { 
  return list('reduction').reduce(function(left, right) {
    return {
      'key': left('key'),
      'row': {
        'time': left('row')('time'),
        'values': left('row')('values').union(right('row')('values'))
      }
    }
  })
})

也许我需要添加一些东西或改变一切?

谢谢。

您可能想要这样的东西:

r.table('test').orderBy('time').concatMap(function(row) {
  return row('data').coerceTo('array');
}).group(function(pair) {
  return pair(0);
}).map(function(pair) {
  return pair(1);
}).ungroup().map(function(group) {
  return {
    key: group('group'),
    rows: group('reduction').do(function(x) {
      return r.range(x.count().sub(2)).map(function(i) {
        return {
          time: i,
          values: r.range(3).map(function(o) {
            return x(i.add(o));
          }).coerceTo('array')
        };
      }).coerceTo('array');
    })
  };
})

(其中 .sub(2).range(3) 需要根据宽度和重叠度进行更改。)

这与 mlucy 的解决方案非常相似,但它并不假设 time 字段是连续的整数。数据在下面的 concatMap 之前按 time 排序 - 对于大型数据集,这应该使用索引来完成。

r.expr(data)
 .orderBy('time')
 .concatMap(function (row) {
   return row('data').coerceTo('array').map(function (pair) {
     return { key: pair(0), value: pair(1), time: row('time') };
   });
 })
 .group('key')
 .ungroup()
 .map(function (g) {
   let rows = g('reduction').count().do(function (c) {
     return r.range(c.sub(2)).map(function (i) {
       let values = r.range(3).map(function (j) {
         return g('reduction')(i.add(j))('value');
       }).coerceTo('array');
       return { 'time': g('reduction')(i)('time'), 'values': values };
     }).coerceTo('array');
   });
   return { key: g('group'), rows: rows };
 })