Агрегирование массива полей объектов с использованием вычисления рейтинга мангуста

#node.js #mongodb #aggregation-framework

Вопрос:

У меня есть модель продукта, которая выглядит так:

 {
   "name":"Natural Product",
   "ratings":[
      {
         "user":"5fdce4bd75dbe4864fcd5001",
         "rating":5
      },
      {
         "user":"5fdce4bd75dbe4864fcd5002",
         "rating":4
      }
   ]
}
 

Я попытался получить среднюю оценку модели продукта, используя запрос ниже

 db.products.aggregate([
  {$match: {
    _id: {$exists: true}
  }},
  {$group: {_id: "$_id", rating: { $avg: "$ratings.rating"}}}
])
 

Но тогда ответ, который я получаю, выглядит так:

 { "_id" : ObjectId("60baf573246539ec265efd41"), "rating" : null }
 

Пытаясь понять, в чем проблема, я вставил новые фиктивные данные только с небольшой разницей в структуре, которая выглядит следующим образом:

 {
   "name":"Natural Product",
   "ratings":{
     "user": "5fdce4bd75dbe4864fcd5001",
     "rating": 5
   }
}
 

Это дало мне такой разумный ответ:

 { "_id" : ObjectId("60bafb72246539ec265efd42"), "rating" : 5 }
 

Как я должен запросить базу данных, чтобы получить среднее значение оценок в формате массива, пожалуйста?

Комментарии:

1. добавьте новый этап после этапа $match { $unwind: "$ratings" } , это приведет к деконструированию массива рейтингов.

Ответ №1:

$avg можно использовать на этапе $project, если у вас более новая версия, чем mongodb server v3.2

 db.products.aggregate(
[
    {
        $project: {
            _id: 1,
            rating: { $avg: "$ratings.rating" }
        }
    }
])
 

https://mongoplayground.net/p/uehHGxI3ybU

Ответ №2:

Выполнение этого на массиве объектов сбивает с толку. Монго не знает, к какому элементу массива обращаться. Так что нам это нужно для unwind того, чтобы разобрать его.
Это сработает

 db.collection.aggregate([
  {
    $match: {
      _id: {
        $exists: true
      }
    }
  },
  {
    $unwind: "$ratings"
  },
  {
    $group: {
      _id: "$_id",
      rating: {
        $avg: "$ratings.rating"
      }
    }
  }
])
 

Рабочий пример для игровой площадки mongo