Sobes.tech
Senior

Тавре язучысыз, үзегезнең мини блогыгызны идарә итәсез һәм анда мәкаләләр урнаштырасыз. Блогыгызның кулланучылары (укытучылар) кергәч, аларны карап/укый алалар. Һәр мәкалә өчен уникаль караулар санын көненә исәпләү функциясен тормышка ашырырга кирәк. Функциональ таләпләр: - Бүгенге статистика: автор үзенең мәкаләсенә бүген күпме уникаль кулланучы караганын күрә ала (мәгълүматлар реаль вакытта җыела). - Узган көннәрнең статистикасы: автор теләсә кайсы узган көннең статистикасын күрә ала (мәсәлән, кичә). Техник чикләүләр һәм шартлар: - Приложение бер серверда эшли (бер под) - Иске саклау - Вакыт UTC0да

sobes.tech AI

Ҷавоб аз AI

Для подсчёта уникальных просмотров статей за день с учётом требований и ограничений (один сервер, in-memory, время UTC0) можно реализовать следующую схему:

  • Для каждого дня и каждой статьи хранить множество уникальных ID пользователей, которые просмотрели статью в этот день.
  • Для текущего дня данные накапливаются в реальном времени.
  • Для прошедших дней данные сохраняются в отдельной структуре (например, в мапе с ключом дата+статья).

Пример на Go:

import (
    "sync"
    "time"
)

// Структура для хранения просмотров
// map[date][articleID] -> set of userIDs
var (
    mu sync.RWMutex
    views = make(map[string]map[string]map[string]struct{})
)

func getDateUTC(t time.Time) string {
    return t.UTC().Format("2006-01-02")
}

// Функция для регистрации просмотра
func RegisterView(articleID, userID string) {
    date := getDateUTC(time.Now())

    mu.Lock()
    defer mu.Unlock()

    if _, ok := views[date]; !ok {
        views[date] = make(map[string]map[string]struct{})
    }
    if _, ok := views[date][articleID]; !ok {
        views[date][articleID] = make(map[string]struct{})
    }
    views[date][articleID][userID] = struct{}{}
}

// Получить количество уникальных просмотров за конкретный день
func GetUniqueViews(articleID, date string) int {
    mu.RLock()
    defer mu.RUnlock()

    if dayData, ok := views[date]; ok {
        if users, ok := dayData[articleID]; ok {
            return len(users)
        }
    }
    return 0
}

Особенности:

  • Используем map с вложенными map для хранения уникальных пользователей.
  • Для уникальности пользователей используем множество (map[string]struct{}).
  • Время по UTC, чтобы корректно группировать просмотры по дате.
  • Для статистики за прошедшие дни просто обращаемся к нужной дате.

Так как приложение работает на одном сервере и in-memory, такой подход будет работать эффективно. При необходимости можно добавить периодическую очистку старых данных.