Перейти к основному содержимому

Оценка (Rating)

Поле типа Оценка используется для хранения рейтингов и оценок в виде звезд или чисел.

Основные характеристики

  • Тип данных: Число (обычно 0-5 или 0-10)
  • Отображение: Звезды, сердца, числа, прогресс-бар
  • Точность: Целые числа или половинки (0.5)
  • Диапазон: Настраиваемый (обычно 1-5 или 1-10)

Настройки поля

При создании поля типа "Оценка" доступны следующие настройки:

  • Название поля: Отображаемое имя поля
  • Системное имя: Уникальный идентификатор для API
  • Описание: Подсказка для пользователей
  • Обязательное поле: Требовать выбора оценки
  • Максимальное значение: Обычно 5 или 10
  • Разрешить половинки: 0.5, 1.5, 2.5 и т.д.
  • Стиль отображения: Звезды, сердца, числа, точки
  • Цвет: Цвет активных элементов

Варианты отображения

Звезды (★)

{
"name": "rating",
"type": "rating",
"max": 5,
"style": "stars",
"color": "#FFD700"
}

Отображение: ★★★★☆ (4 из 5)

Сердца (♥)

{
"name": "favorite_level",
"type": "rating",
"max": 5,
"style": "hearts",
"color": "#FF0000"
}

Отображение: ♥♥♥♡♡ (3 из 5)

Числа

{
"name": "score",
"type": "rating",
"max": 10,
"style": "numeric"
}

Отображение: 7/10

Точки

{
"name": "difficulty",
"type": "rating",
"max": 5,
"style": "dots"
}

Отображение: ●●●○○ (3 из 5)

Примеры использования

Рейтинг товара

{
"name": "rating",
"type": "rating",
"max": 5,
"allowHalf": true,
"default": 0
}

Оценка качества

{
"name": "quality_score",
"type": "rating",
"max": 10,
"required": true
}

Уровень сложности

{
"name": "difficulty",
"type": "rating",
"max": 5,
"style": "dots",
"labels": ["Очень легко", "Легко", "Средне", "Сложно", "Очень сложно"]
}

Удовлетворенность клиента

{
"name": "satisfaction",
"type": "rating",
"max": 5,
"style": "stars",
"required": true
}

Работа через API

Создание записи

const review = await emd.database.collection('reviews').create({
product: productId,
user: userId,
rating: 4.5,
comment: 'Отличный товар!'
});

Получение рейтинга

const review = await emd.database.collection('reviews').get(reviewId);

console.log(review.rating);
// {
// value: 4.5,
// max: 5,
// formatted: "★★★★½",
// percent: 90
// }

Обновление рейтинга

await emd.database.collection('reviews').update(reviewId, {
rating: 5
});

Поиск и фильтрация

Отзывы с высоким рейтингом

const topReviews = await emd.database.collection('reviews').find({
rating: { $gte: 4 }
});

Отзывы с низким рейтингом

const lowReviews = await emd.database.collection('reviews').find({
rating: { $lte: 2 }
});

Отзывы с конкретным рейтингом

const fiveStarReviews = await emd.database.collection('reviews').find({
rating: 5
});

Агрегация и статистика

Средний рейтинг

const avgRating = await emd.database.collection('reviews').aggregate([
{
$match: { product: productId }
},
{
$group: {
_id: null,
averageRating: { $avg: '$rating' },
totalReviews: { $sum: 1 }
}
}
]);

console.log(avgRating[0]);
// {
// averageRating: 4.3,
// totalReviews: 156
// }

Распределение рейтингов

const distribution = await emd.database.collection('reviews').aggregate([
{
$match: { product: productId }
},
{
$group: {
_id: '$rating',
count: { $sum: 1 }
}
},
{
$sort: { _id: -1 }
}
]);

console.log(distribution);
// [
// { _id: 5, count: 80 },
// { _id: 4, count: 50 },
// { _id: 3, count: 20 },
// { _id: 2, count: 5 },
// { _id: 1, count: 1 }
// ]

Обновление среднего рейтинга товара

const avgRating = await emd.database.collection('reviews').aggregate([
{
$match: { product: productId }
},
{
$group: {
_id: null,
average: { $avg: '$rating' },
count: { $sum: 1 }
}
}
]);

if (avgRating.length > 0) {
await emd.database.collection('products').update(productId, {
average_rating: avgRating[0].average,
reviews_count: avgRating[0].count
});
}

Отображение в интерфейсе

Звезды

function renderStars(rating, max = 5) {
const fullStars = Math.floor(rating);
const hasHalfStar = rating % 1 >= 0.5;
const emptyStars = max - fullStars - (hasHalfStar ? 1 : 0);

return '★'.repeat(fullStars) +
(hasHalfStar ? '½' : '') +
'☆'.repeat(emptyStars);
}

console.log(renderStars(4.5)); // "★★★★½"

HTML с CSS

function renderRatingHTML(rating, max = 5) {
return `
<div class="rating">
${Array.from({ length: max }, (_, i) => {
const filled = i < Math.floor(rating);
const half = i === Math.floor(rating) && rating % 1 >= 0.5;

return `
<span class="star ${filled ? 'filled' : half ? 'half' : ''}">

</span>
`;
}).join('')}
<span class="rating-value">${rating.toFixed(1)}</span>
</div>
`;
}

Интерактивный рейтинг

function createRatingInput(currentRating = 0, max = 5) {
const container = document.createElement('div');
container.className = 'rating-input';

for (let i = 1; i <= max; i++) {
const star = document.createElement('span');
star.className = 'star';
star.textContent = '★';
star.dataset.value = i;

if (i <= currentRating) {
star.classList.add('filled');
}

star.addEventListener('click', () => {
// Обновить рейтинг
updateRating(i);
});

container.appendChild(star);
}

return container;
}

Валидация

Проверка диапазона

{
"name": "rating",
"type": "rating",
"min": 1,
"max": 5
}
try {
await emd.database.collection('reviews').create({
rating: 6 // Больше максимума
});
} catch (error) {
console.error(error.message); // "Rating must be between 1 and 5"
}

Типичные сценарии

Отзывы о товарах

const review = await emd.database.collection('reviews').create({
product: productId,
user: userId,
rating: 5,
title: 'Отличный товар!',
comment: 'Очень доволен покупкой',
verified_purchase: true
});

Оценка статьи

const rating = await emd.database.collection('article_ratings').create({
article: articleId,
user: userId,
rating: 4,
helpful: true
});

Оценка сотрудника

const evaluation = await emd.database.collection('evaluations').create({
employee: employeeId,
manager: managerId,
performance: 4,
teamwork: 5,
communication: 4,
overall: 4.3
});

Вычисляемые поля

Процент от максимума

{
"name": "rating_percent",
"type": "formula",
"formula": "(record.rating / 5) * 100",
"resultType": "number"
}

Текстовое представление

{
"name": "rating_text",
"type": "formula",
"formula": "record.rating >= 4.5 ? 'Отлично' : record.rating >= 3.5 ? 'Хорошо' : record.rating >= 2.5 ? 'Удовлетворительно' : 'Плохо'",
"resultType": "string"
}

Рекомендации

  • Используйте 5-звездочную шкалу для большинства случаев
  • Разрешайте половинки для более точной оценки
  • Показывайте средний рейтинг и количество отзывов
  • Добавляйте возможность фильтрации по рейтингу
  • Используйте цветовое кодирование (зеленый для высокого, красный для низкого)
  • Не позволяйте пользователям оценивать несколько раз
  • Показывайте распределение рейтингов (гистограмма)

Отличие от других типов

  • Rating vs Number: Rating для оценок с визуализацией, Number для обычных чисел
  • Rating vs Percent: Rating для оценок (1-5), Percent для процентов (0-100)
  • Rating vs Select: Rating для числовых оценок, Select для категорий