从rethinkdb获取多个平均值和计数的最有效方法

时间:2017-05-18 22:23:09

标签: node.js rethinkdb rethinkdb-javascript

我正在创建一个Web应用程序,它从表单中收集信息,将它们(例如年龄,身高和体重)插入rethinkdb数据库,然后通过socket.io显示简单的描述性统计数据。 / p>

目前,我使用r.expr()来运行多个查询,例如

r.expr({
mean1: r.db(…).table(…).avg(…),
mean2: r.db(…).table(…).group(…).avg(…).mul(10).round().div(10).ungroup(),
count: r.db(…).table(…).count()
}).run(conn, (err, res) => {
...

构造一个包含我感兴趣的计数和平均值的对象,然后使用io.emit()将它们发送到客户端进行显示,每次添加新条目时都会更新。

对我来说,这看起来并不高效,而且我猜测有更好的方法 - 也许只用一个查询 - 但我对ReQL非常缺乏经验和查询语言一般。

此外,有没有更好的方法在分组后使用任意精度或更复杂的数值运算进行舍入,而不是像上面那样?

1 个答案:

答案 0 :(得分:0)

要一次执行多次缩减,您可以手动将它们拆分为单独的mapreduce操作。类似的东西:

r.table(...).map(
    row => ({
        count: 1,
        sum: row('a'),
        groups: r.object(row('group'), {count: 1, sum: r.row('a')})
    })
).reduce(
    (left, right) => ({
        count: left('count').add(right('count')),
        sum: left('sum').add(right('sum')),
        groups: left.keys().setUnion(right.keys()).map(
                key => [key, {
                    count: left(key)('count').default(0).add(right(key)('count').default(0)),
                    sum: left(key)('sum').default(0).add(right(key)('sum').default(0))
                }]
            ).coerceTo('object')
    })
).do(
    res => ({
        count: res('count'),
        mean1: res('sum').div(res('count')),
        mean2: res('groups').coerceTo('array').map(
            pair => [pair(0), pair(1).do(x => x('sum').div(x('count')).mul(10).round().div(10)]
    }).coerceTo('object')
)

原样可能效率不高,但可以进一步优化。

您可以使用more complex mathematical operations

执行r.js