有没有一种方法可以在MongoDB聚合管道中获取字段的平方根?我在想这样的事情:
db.collection.aggregate(
{ $group: _id: null, sum: { $sum: "$values" }},
{ $project: { answer: { $sqrt: "$sum" }}})
我知道$sqrt不存在,也不存在任何幂运算符,但是有没有一种方法可以在聚合管道中实现这一点?我知道这可以在map-reduce中使用用户定义的函数来完成,但在聚合管道中可能吗?
3条答案
按热度按时间ffdz8vbo1#
正如@AnandJayabalan所指出的,**
$sqrt
**运算符将随MongoDB版本3.2发布,其语法为:在您的示例中,这将是
在撰写本文时,作为一种变通方法,John Page关于calculating square roots within the aggregation framework的链接博客文章使用算术原语通过牛顿法计算平方根。
为了解释这个算法是如何工作的,假设你想找到一个正数
N
的平方根。牛顿的方法涉及对一个数字A
进行有根据的猜测,当平方时,将接近等于N
。例如,如果
N = 121
,您可能会猜测A = 10
,因为A² = 100
,这是一个接近的猜测,但您可以做得更好。该方法中使用的方程是 * 牛顿平方根方程 *:
何处
N
是一个正数,您要求其平方根√
是平方根符号≈
表示“近似等于……”A
是你的猜测如果需要,牛顿法允许您多次重复估计,以接近一个精确的数字。以John Page的例子
N = 29
为例,您可以猜测A = 5
,然后将这些值输入到公式和算法步骤中**a.**从猜测
A = 5
开始**B.**将N除以猜测值
(29/5 = 5.9)
**c.**将其添加到猜测
(5.9 + 5 = 10.9)
中**d.**然后将结果除以2
(10.9/2 = 5.45)
e.将其设置为新的猜测
A = 5.45
,并重复,从B开始。5.45 5.38555 5.38516
经过2次迭代,答案是
3.1623
,接近平方根的精确值。现在,使用聚合框架(来自John Page的博客文章)并将其应用到您的示例中,聚合管道将是:
qnakjoqk2#
Mongo 3.2将有一个原生的sqrt method for the aggregation framework。
如果参数解析为null值或引用的字段丢失,则$sqrt返回null。如果参数解析为NaN,则$sqrt返回NaN。
负数上的$sqrt错误。
nhaq1z213#
这篇文章很老了,但是我们需要编写自己的立方根实现来替换
$pow(x,1/3)
。原因是我们使用AWS DocumentDB不必托管和管理我们自己的MongoDB数据库。但是,AWS Document DB在其两个版本中都不支持运算符$sqrt
或$pow
。我也不明白他们为什么不支持它。我们实现了两个版本,使用Netwon的方法和Halley的方法(因为后者收敛得更快)。从技术上讲,它们也是基于使用聚合框架的@chridram的答案。您可以复制确切的命令以重现它:
启动一个docker容器并执行
mongosh
:Netwon方法:
Halley方法:
有关实际公式的更多详细信息,请参见https://en.wikipedia.org/wiki/Cube_root。
进一步的改进可以是使用
$addFields
而不是$project
。它更容易阅读。参见https://www.mongodb.com/docs/manual/reference/operator/aggregation/addFields/