计算数组中评分的平均值,然后将字段添加到MongoDB中的原始文档

时间:2019-01-19 19:32:05

标签: mongodb

我有一个文档,其中包含一个名为“等级”的字段。这是一个对象数组,每个对象都包含userId和ratingValue

ratings: Array
 0: Object
  userId: "uidsample1"
  ratingValue: 5
 1: Object
  userId:"uidsample2"
  ratingValue:1.5

当阵列中的一个评级被更新或添加时,我想做一个聚合管道来计算新的平均值。然后,我想将该值作为一个称为averageRating的新字段放入文档中。

我尝试平仓,然后$ avg的$ add字段:“ ratings.ratingValue”,但是它添加到平仓的文档中,但没有得到平均值。看起来像这样(自从在指南针上测试之后就不完全如此)

db.test.aggregate{
  [
    {
    $unwind: {
    path: "$ratings"
    }
  },
  { 
    $addFields {
    averageRating: {
    $avg: "$ratings.ratingValue"
      }
    }

      }
    ]
  }

对此有什么好的查询结构?

2 个答案:

答案 0 :(得分:1)

py4j.protocol.Py4JError: An error occurred while calling z:org.apache.spark.sql.functions.abs. Trace: **py4j.Py4JException: Method abs([class java.lang.Integer]) does not exist at** py4j.reflection.ReflectionEngine.getMethod(ReflectionEngine.java:318) at py4j.reflection.ReflectionEngine.getMethod(ReflectionEngine.java:339) at py4j.Gateway.invoke(Gateway.java:276) at py4j.commands.AbstractCommand.invokeMethod(AbstractCommand.java:132) at py4j.commands.CallCommand.execute(CallCommand.java:79) at py4j.GatewayConnection.run(GatewayConnection.java:238) at java.lang.Thread.run(Thread.java:745) 之后使用$group,如下所述计算 averageRating 。聚合是读取操作。您需要稍后再更新文档。

$unwind

答案 1 :(得分:1)

您实际上不需要$unwind$group来计算平均值,这些操作成本很高

您可以简单地将$addFields$avg

db.col.aggregate([
    {$addFields : {averageRating : {$avg : "$ratings.ratingValue"}}}
])

样本收集和汇总

> db.t62.drop()
true

> db.t62.insert({data : {ratings : [{val : 1}, {val : 2}]}})
WriteResult({ "nInserted" : 1 })

> db.t62.find()
{ "_id" : ObjectId("5c44d9719d56bf65be5ab2e6"), "data" : { "ratings" : [ { "val" : 1 }, { "val" : 2 } ] } }

> db.t62.aggregate([{$addFields : {avg : {$avg : "$data.ratings.val"}}}])
{ "_id" : ObjectId("5c44d9719d56bf65be5ab2e6"), "data" : { "ratings" : [ { "val" : 1 }, { "val" : 2 } ] }, "avg" : 1.5 }