同一文档

时间:2016-06-08 14:03:59

标签: php mongodb aggregation-framework

我的数据库中存储的文档与“架构”完全相同。每个文档都有三个浮点值(键是“A”,“B”和“C”),我需要做的是将每个文档输出为三个浮点数。

我还需要除以100,所以我的计算是(A + B + C)/ 3/100。据我所知,我需要将每个文档作为一个不同的输出进行投影,但$ group在这里没用(因为我没有对所有文档进行平均,只是每个文档)。

我首先需要能够将其编写为MongoDB命令,然后将其转换为PHP。我想我将能够完成PHP部分,但我需要的是一些帮助开始实际的MongoDB命令......

db.measurements.aggregate(   )

我的数据存储如下:

{ "_id" : ObjectId(xxx), "A": 22.34, "B": 23.32, "C": 75.32, "device_id": 3 }
{ "_id" : ObjectId(xxx), "A": 22.34, "B": 23.32, "C": 75.32, "device_id": 3 }
{ "_id" : ObjectId(xxx), "A": 22.34, "B": 23.32, "C": 75.32, "device_id": 3 }

当我提交获取请求时,我需要我的数据如下:

{ "_id" : ObjectId(xxx), "Average of A,B,C": 40.50, "device_id": 3 }
{ "_id" : ObjectId(xxx), "Average of A,B,C": 40.50, "device_id": 3 }
{ "_id" : ObjectId(xxx), "Average of A,B,C": 40.50, "device_id": 3 }

经过一些进一步的研究,似乎聚合不是我应该在这里使用的方法?如果我在插入数据库之前计算我的php模型中的平均值,然后通过find()方法检索我的文档会不会更好?

2 个答案:

答案 0 :(得分:5)

您基本上需要的是一个 $project 管道聚合 - 它会使用可用的 arithmetic operators 计算您的平均值,并会修改在同一个管道中的结果是将字段作为计算((A + B + C)/3)/100的表达式(如果你想要一个百分比,那么你需要乘以而不是除法,即计算是((A + B + C)/3)*100)。通过以下操作总结说明:

db.measurements.aggregate([
    {
        "$project": {               
            "device_id": 1,
            "Average of A,B,C": {
                "$divide": { // ( A + B + C )/3 )/100
                    {
                        "$divide": [ // (A + B + C )/3
                            { "$add": [ "$A", "$B", "$C" ] }, // A + B + C
                            3
                        ]
                    },
                    100
                }
            }
        }
    }
])

话虽这么说,最好在应用层执行繁重或复杂的计算任务,让mongo最好地完成数据持久性任务。

答案 1 :(得分:3)

从MongoDB 3.2开始,我们可以使用带有方括号[]的{​​{3}}累加器运算符直接在$avg阶段创建新的数组字段,以便有效地执行此操作。

当然我们还需要$project算术聚合运算符来将值除以100

db.measurements.aggregate(
    [ 
        { "$project": { 
            "result": { 
                "$divide": [
                    { "$avg": [ "$a", "$b", "$c" ] }, 
                    100 
                ] 
            } 
        }} 
    ]
)

PHP中的翻译给出:

db.measurements.aggregate(
    array(
        array("$project" => array( 
            "result" => array( 
                "$divide" => array(
                    "$avg" => array("$a", "$b", "$c"), 
                    100 
                )
            )
        ))
    )
)