Search by

ws-stat / simple-metrics-stats

ladovod444

Symfony data analytics and collection bundle

Package info

github.com/ladovod444/simple-metrics-stats

Type:symfony-bundle

pkg:composer/ws-stat/simple-metrics-stats

Statistics

Installs: 6

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v1.0.2 2026-09-21 16:46 UTC

This package is auto-updated.

Last update: 2026-09-24 08:19:03 UTC


README

Demo package

Symfony-бандл для сбора и анализа данных по аналитике.

Возможности

  • Сбор аналитики
  • Режим --dry-run для предварительного просмотра
  • Интерактивное подтверждение

Установка

composer require ws/simple-metrics-stats

После установки пакета выполните

php bin/console doctrine:migrations:diff

php bin/console doctrine:migrations:migrate

в основном проекте

Описание сущностей Keyword и KeywordPosition

Keyword

Хранит метаданные о ключевой фразе. Сам по себе он не хранит историю изменений позиций (для этого есть связанная сущность KeywordPosition), он выступает как "якорь" или справочник, к которому привязываются ежедневные замеры позиций.

(Поля таблицы keywords БД / св-ва сущности)

  • $id (int): Первичный ключ (Primary Key). Генерируется автоматически базой данных (GeneratedValue).

  • $site (Site): Связь "Многие-к-одному" (ManyToOne). Указывает, какому именно сайту принадлежит это ключевое слово. onDelete: 'CASCADE' означает, что если сайт будет удален из системы, все привязанные к нему ключевые слова удалятся автоматически.

  • $phrase (string): Сама поисковая фраза (например, "купить iphone 18"). Ограничена 255 символами.

  • $region (string): Код региона для поиска (например, "ru", "213" для Москвы в Яндекс.Вебмастере, "saint-petersburg"). По умолчанию равен "ru".

  • $createdAt (\DateTimeImmutable): Дата и время добавления ключевого слова в систему. Используется неизменяемый объект даты (Immutable), что является хорошей практикой, чтобы случайно не изменить дату создания. По умолчанию ставится текущее время (CURRENT_TIMESTAMP).

  • $positions (Collection): Связь "Один-ко-многим" (OneToMany). Это коллекция объектов KeywordPosition, хранящих историю позиций данного ключевого слова по дням.

KeywordPosition

Фиксирует состояние поисковой выдачи для заданного ключевого слова в конкретный день. Он отвечает на вопросы: "На каком месте был сайт по фразе X вчера?", "Как менялась частотность запроса за последний месяц?".

(Поля таблицы keyword_positions БД / св-ва сущности)

  • $id (int): Первичный ключ (Primary Key). Автоинкремент.

  • $keyword (Keyword): Связь "Многие-к-одному" (ManyToOne). Указывает, к какому именно ключевому слову относится эта запись. onDelete: 'CASCADE' гарантирует, что при удалении ключевого слова вся его история позиций будет автоматически и безопасно удалена из базы данных, не оставляя "висячих" (orphan) записей.

  • $date (\DateTimeImmutable): Дата замера позиции. Используется тип DATE_IMMUTABLE (хранит только дату, без времени), что идеально подходит для ежедневной статистики и экономит место в БД. Неизменяемость (Immutable) защищает от случайных ошибок в коде, которые могли бы изменить дату исторической записи.

  • $position (?int): Текущая позиция в выдаче. Важная деталь: Поле nullable: true. Как указано в комментарии, NULL означает, что сайт не найден в ТОП-100 (или в другом заданном диапазоне парсинга).

  • $searchVolume (int): Поисковая частотность (объем поиска) на момент замера. Частотность запросов меняется со временем (сезонность, изменение алгоритмов Яндекса/Google). Хранение частотности в ежедневном снапшоте позволяет строить исторически точные отчеты: "В январе частотность была 1000, а в феврале упала до 500, хотя позиция осталась прежней".

Принцип работы

  1. Система создает объект Keyword для фразы "купить iphone" и региона "Москва" для сайта example.com.

  2. Раз в день скрипт проверяет позиции в Яндексе/Google.

  3. Скрипт создает новый объект KeywordPosition (с датой, позицией 5, поисковиком "yandex") и добавляет его в этот Keyword через метод addPosition().

  4. При вызове $entityManager->flush() Doctrine одним транзакционным запросом сохранит и ключевое слово (если оно новое), и его новую позицию в историю.

DailyStat

DailyStat - это агрегированный дашборд за день. Он объединяет в одной таблице метрики как из систем веб-аналитики (Яндекс.Метрика / Google Analytics), так и из панелей вебмастера (Яндекс.Вебмастер / Google Search Console). фиксирует "снимок" (снапшот) всех ключевых показателей сайта за конкретную дату. Это позволяет строить сводные графики трафика, видимости и поведенческих факторов без необходимости каждый раз делать сложные JOIN и агрегации (SUM, AVG) по миллионам записей таблицы keyword_positions.

(Поля таблицы daily_stats БД / св-ва сущности)

Поля логически делятся на 4 группы:

А. Идентификация и связи:

  • $id: Первичный ключ.

  • $site: Связь "Многие-к-одному" с сайтом. onDelete: 'CASCADE' гарантирует очистку статистики при удалении сайта.

  • $date: Дата, за которую собраны показатели (DATE_IMMUTABLE).

  • $createdAt: Время создания записи в базе (автоматически CURRENT_TIMESTAMP).

Б. Метрики трафика (Аналитика - Метрика/GA):

  • $visits: Количество визитов (сессий).

  • $pageviews: Количество просмотров страниц.

  • $bounceRate: Показатель отказов (в процентах).

  • $avgSessionSec: Средняя длительность сеанса в секундах.

В. Метрики поисковой выдачи (Вебмастер/GSC):

  • $impressions: Количество показов сайта в поисковой выдаче.

  • $clicks: Количество переходов из поиска.

  • $ctr: CTR (Click-Through Rate, кликабельность) в процентах (DECIMAL).

  • $avgPosition: Средняя позиция сайта по всем запросам за день (DECIMAL).

Г. SEO-здоровье (производные метрики):

  • $competitorsCount: Количество сайтов-конкурентов в ТОП-10 (полезно для оценки сложности ниши).

  • $top3Count: Количество ключевых слов сайта, находящихся в ТОП-3 выдачи.

Принцип работы

Система работает по принципу агрегации на записи (Write-heavy, Read-light):

  • Раз в сутки (или по расписанию) скрипт собирает сырые данные из API Яндекса/Google.
  • Он рассчитывает сводные показатели (общие клики, средний CTR, количество слов в ТОП-3).
  • Он создает одну запись DailyStat за этот день и сохраняет её.
  • Когда пользователь открывает дашборд, фронтенд делает один быстрый запрос к API, который отдает массив объектов DailyStat за выбранный период. График строится мгновенно.

Site

Представляет собой корневую сущность (Aggregate Root) всей SEO-системы. Является центральным узлом, который объединяет всё воедино.

(Поля таблицы sites БД / св-ва сущности)

  • $id: Первичный ключ.

  • $domain: Доменное имя (например, example.com). Важно: Атрибут unique: true гарантирует на уровне базы данных, что один и тот же домен нельзя добавить в систему дважды.

  • $name: Человеко-понятное название проекта (например, "Интернет-магазин шин"). Поле nullable: true, так как для некоторых проектов достаточно только домена.

  • $createdAt: Дата добавления сайта в систему (DATETIME_IMMUTABLE).

  • $keywords: Коллекция (OneToMany) всех ключевых слов, отслеживаемых для этого сайта.

  • $dailyStats: Коллекция (OneToMany) ежедневных сводных отчетов для этого сайта.

Итоговая архитектура вашей системы

Иерархия базы данных:

Site (Корень): Хранит домен. Управляет удалением всего, что с ним связано.

    DailyStat (Ветвь 1): Хранит агрегированные цифры за день (трафик, клики, CTR) для этого сайта.

        Keyword (Ветвь 2): Хранит конкретную фразу и регион для этого сайта.

            KeywordPosition (Лист): Хранит историю позиций (снапшоты) для конкретного Keyword в конкретный день.