RethinkDB - 如何合并和平均对象

时间:2015-12-23 23:34:24

标签: rethinkdb

我的文件结构如下:

[
  {
    'post': 1,
    'tags': [1, 2],
    'poll': {
      'a': 2,
      'b': 2
    }
  },
  {
    'post': 1,
    'tags': [3],
    'poll': {
      'a': 4,
      'b': 6
    }
  },
]

如何合并它们,以便tags成为这些帖子中所有代码的联合,poll将被平均?从上面的示例中,结果应如下所示:

[
  {
    'post': 1,
    'tags': [1, 2, 3],
    'poll': {
      'a': 3,
      'b': 4
    }
  }
]

感谢。

2 个答案:

答案 0 :(得分:0)

我认为我们可以使用map-reduce,因为我们将许多文档转换为单个文档。这样的事情应该有效:

r.expr([
  {
    'post': 1,
    'tags': [1, 2],
    'poll': {
      'a': 2,
      'b': 2
    }
  },
  {
    'post': 1,
    'tags': [3],
    'poll': {
      'a': 4,
      'b': 6,
    }
  },
])
  .merge(function(doc) {
    return {
      'poll': doc('poll').coerceTo('array').map(function(poll) { return [poll(0), [poll(1)]] }).coerceTo('object')
    }
  })  

  .reduce(function(left, right) {
    return {
      'post': left('post'),
      'tags': left('tags').setUnion(right('tags')),
      'poll': left('poll').keys().setUnion(right('poll').keys()).map(function(k) {
        return [k, 
          left('poll')(k).default([]).union(right('poll')(k).default([]))
          ]
      })
    }
  })

  .merge(function(doc) {
    return {
      poll: doc('poll').map(function(poll) {
        return [poll(0), poll(1).avg()]
      }).coerceTo('object')
    }
  })

这会产生:

{
    "poll": {
        "a": 3,
        "b": 4
    },
    "post": 1,
    "tags": [1, 2, 3]
}

答案 1 :(得分:0)

最初由kureikain提出的修正版:

r.expr([
  {
    'post': 1,
    'tags': [1, 2],
    'poll': {
      'a': 2,
      'b': 2
    }
  },
  {
    'post': 1,
    'tags': [3],
    'poll': {
      'a': 4,
      'b': 6,
    }
  },
  {
    'post': 1,
    'tags': [2],
    'poll': {
      'a': 1,
      'b': 3,
    }
  },
])
.merge(function(doc) {
  return {
    'poll': doc('poll').coerceTo('array').map(function(poll) { return [poll(0), [poll(1)]] }).coerceTo('object')
  }
})  
.reduce(function(left, right) {
  return {
    'post': left('post'),
    'tags': left('tags').setUnion(right('tags')),
    'poll': left('poll').keys().map(function(k) {
      return [k, left('poll')(k).default([]).union(right('poll')(k).default([]))]
    }).coerceTo('object')
  }
})
.merge(function(doc) {
  return {
    poll: doc('poll').keys().map(function(k) {
      return [k, doc('poll')(k).avg()]
    }).coerceTo('object')
  }
})