Оценка (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 для категорий