在一个 rethinkdb 查询中聚合多个字段

Aggregate multiple fields in one rethinkdb query

如何减少/聚合一个table中的多个字段?这似乎效率不高:

r.object(
  'favorite_count', 
  r.db('twitterdb').table('tweets').map(tweet => tweet('favorite_count')).avg().round(),
  'retweet_count',
   r.db('twitterdb').table('tweets').map(tweet => tweet('retweet_count')).avg().round()
  )

(预期)结果:

{

    "favorite_count": 17 ,
    "retweet_count": 156

}

我不确定是否可以使用 RethinkDB 的 built-ins 一次性让 RethinkDB 像您想要的那样工作,但是您可以非常轻松地自己实现 avg 功能:

r.db('twitterdb')
  .table('tweets')
  .fold(
    {_: 0, favorite_count: 0, retweet_count: 0},
    (a, tweet) => ({
      _: a('_').add(1),
      favorite_count: a('favorite_count').add(tweet('favorite_count')),
      retweet_count: a('retweet_count').add(tweet('retweet_count'))
    })
  )
  .do(a => ({
    favorite_count: r.branch(a('_').gt(0), a('favorite_count').div(a('_')).round(), null),
    retweet_count: r.branch(a('_').gt(0), a('retweet_count').div(a('_')).round(), null)
  }))

我有 quickly-tested 上面的一小部分数据,启用查询分析显示至少有 /2 分片访问和更少的执行时间。 但是我不确定整体分析器的输出,我不认为我可以解释它的细节(我相信原生 avg 更优化,但至少在两轮中访问数据看起来更便宜) . 此外,此自定义 avg 函数实现对 0 元素更友好,不会引发错误。

如果数组的长度已知(例如7430),这样会更快:

  r.db('twitterdb').table('tweets')
  .reduce((agg, item) => {
    return {
      favorite_count: agg('favorite_count').add(item('favorite_count')),
      retweet_count: agg('retweet_count').add(item('retweet_count'))
      }
    })
   .do(result => r.object('favorite_count', result('favorite_count').div(7430).round(), 'retweet_count', result('retweet_count').div(7430).round()))