вставка нового поля с помощью $ avg mongodb

#mongodb #meteor #average

#mongodb #meteor #среднее

Вопрос:

Каждый раз, когда пользователь оценивает какое-либо сообщение от 1 до 5, это число записывается (как значение свойства) с идентификатором пользователя в качестве имени свойства.

 "starRatingByUser" : {
    "iZxSjCduTjfCQbmf9" : 3,
    "LvBr6a427ofuvXFMp" : 4,
    "gfhfhfh98rtgfXFft" : 5
}
 

Возможно ли вставлять (обновлять) новое поле («starRatingAverage») со средним значением всех оценок каждый раз, когда пользователи добавляют или обновляют рейтинг?

Пример:

 "starRatingAverage": 4,
"starRatingByUser" : {
    "iZxSjCduTjfCQbmf9" : 3,
    "LvBr6a427ofuvXFMp" : 4,
    "gfhfhfh98rtgfXFft" : 5
}
 

У меня есть этот метод:

 Recipes.update(
  { _id: recipeId },
  { $set: { ["starRatingByUser."   this.userId]: star }}
)
 

[пример изображения]
: https://i.stack.imgur.com/CuWbR.png

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

1. это ужасно непонятно, пожалуйста, обновите

2. извините, обновил его

Ответ №1:

В mongodb есть возможность обновления с помощью агрегации. Обновление-документов-с-агрегацией-конвейером

  • Следующий запрос на обновление устанавливает два аргумента. Во-первых, нужно найти документ, во-вторых, выполнить агрегацию

При агрегировании

  • преобразуйте объект в массив, используя $objectToArray для вычисления общего
  • получите размер массива, используя $size и вычислите общее количество, используя $reduce
  • $project чтобы удалить ненужные поля

сценарий

 db.colelction.updateOne(
  {_id:1},
[
  {
    $addFields: {
      stu: {
        "$objectToArray": "$starRatingByUser"
      }
    }
  },
  {
    $addFields: {
      size: {
        $size: "$stu"
      },
      total: {
        $reduce: {
          input: "$stu",
          initialValue: 0,
          in: {
            $add: [
              "$this.v",
              "$value"
            ]
          }
        }
      }
    }
  },
  {
    "$project": {
      starRatingByAverage: {
        "$divide": [
          "$total",
          "$size"
        ]
      },
      starRatingByUser: 1
    }
  }
])
 

Этот запрос проверен и работает нормально