查询mongodb:在数组中使用$avg和$unwind进行聚合

lnlaulya  于 2023-06-29  发布在  Go
关注(0)|答案(1)|浏览(124)

我需要一个查询来返回avgRating,所以我尝试运行以下查询:

db.EVALUATION.aggregate([
  {
    $match: {
      _id: 84820
    }
  },
  {
    $unwind: "$reviews"
  },
  {
    $group: {
      _id: "$_id",
      avgRating: { $avg: "$reviews.rating" }
    }
  }
])

在真实的生活中,返回值需要是avgRating:1.1875(我在python中测试了这个)。但是,我的回报是avgRating:1
示例:

{
  _id: 84820,
  avgRating: 1
}

我怎么能解决这个问题?我不知道mongoDB是否会自动将结果四舍五入为1。如果是这样,我如何使它显示完整的小数?
-code python-

sum= 0
counter= 0

for review in reviews:
   rating = review["rating"]  
   sum += rating 
   counter  += 1

media = sum/ counter

print(media)

文件:

{
  "_id": 84820,
  "name": "Boula",
  "location": {
    "city": "Paris",
  },
  "category": "restaurant",
  "description": "",
  "reviews": [
    {
      "wordsCount": 14,
      "rating": 0,
      "polarity": 10
    },
    {
      "wordsCount": 11,
      "rating": 0,
      "polarity": 5
    },
    {
      "wordsCount": 16,
      "rating": 0,
      "polarity": 5
    },
    {
      "wordsCount": 7,
      "rating": 0,
      "polarity": 10
    },
    {
      "wordsCount": 19,
      "rating": 0,
      "polarity": 10
    },
    {
      "wordsCount": 6,
      "rating": 0,
      "polarity": 10
    },
    {
      "wordsCount": 2,
      "rating": 0,
      "polarity": 5
    },
    {
      "wordsCount": 5,
      "rating": 0,
      "polarity": 5
    },
    {
      "wordsCount": 18,
      "rating": 0,
      "polarity": 5
    },
    {
      "wordsCount": 5,
      "rating": 0,
      "polarity": 5
    },
    {
      "wordsCount": 4,
      "rating": 0,
      "polarity": 10
    },
    {
      "wordsCount": 60,
      "rating": 5,
      "polarity": 10
    },
    {
      "wordsCount": 47,
      "rating": 2,
      "polarity": 5
    },
    {
      "wordsCount": 18,
      "rating": 3,
      "polarity": 5
    },
    {
      "wordsCount": 18,
      "rating": 4,
      "polarity": 5
    },
    {
      "wordsCount": 6,
      "rating": 5,
      "polarity": 5
    }
  ],
  "nbReviews": 16
},

我尝试了很多查询,比如:

db.EVALUATION.aggregate([
  {
    $match: {
      _id: 84820
    }
  },
  {
    $unwind: "$reviews"
  },
  {
    $group: {
      _id: "$_id",
      avgRating: { $avg: { $toDouble: "$reviews.rating" } }
    }
  }
])
db.EVALUATION.aggregate([
  {
    $match: {
      _id: 84820
    }
  },
  {
    $unwind: "$reviews"
  },
  {
    $group: {
      _id: "$_id",
      sumRatings: { $sum: { $convert: { input: "$reviews.rating", to: "decimal" } } },
      countRatings: { $sum: 1 }
    }
  },
  {
    $project: {
      avgRating: { $divide: [ "$sumRatings", "$countRatings" ] }
    }
  }
])
db.EVALUATION.aggregate([
  {
    $match: {
      _id: 84820
    }
  },
  {
    $unwind: "$reviews"
  },
  {
    $group: {
      _id: "$_id",
      ratings: {
        $push: {
          $convert: {
            input: "$reviews.rating",
            to: "decimal",
            onError: 0,
            onNull: 0
          }
        }
      }
    }
  },
  {
    $project: {
      avgRating: { $avg: "$ratings" }
    }
  }
])
w8ntj3qf

w8ntj3qf1#

我觉得你把事情弄得太复杂了。$avg可能就足够了,基于这里记录的数组行为。示例命令:

db.collection.aggregate([
  {
    $project: {
      _id: 1,
      avgRating: {
        $avg: "$reviews.rating"
      }
    }
  }
])

产生以下结果:

[
  {
    "_id": 84820,
    "avgRating": 1.1875
  }
]

Playground demonstration here

相关问题