В предыдущей статье мы подготовили наше тестовое приложение — бота для обмена анонимными сообщениями в Telegram.
Пришло время отобразить все данные, которые мы собрали. Для этого мы будем использовать Redash.
Что лежит в базе
Данные в базе (MongoDB) у нас хранятся в следующем виде.
Пользователь:
{
"_id": {
"$oid": "64908ebc5a1d121b983e2406"
},
"user_id": 5784928745,
"username": "nickname",
"datetime": 1687195324.282187,
"status": "active"
}
Сообщение:
{
"_id": {
"$oid": "64908ec65a1d121b983e2407"
},
"user_id_from": 5784928745,
"user_id_to": "5982379843",
"username_from": "nickname_from",
"username_to": "nickname_to",
"content": "Hi",
"message_type": "question",
"datetime": 1687195334.6866229
}
Пишем запросы
Запросы к MongoDB — это отдельный вид искусства, я считаю. Давайте попробуем им хоть немного овладеть.
Активные пользователи
Получим количество активных пользователей:
{
"collection": "users",
"query": {
"status": "active"
},
"count": true
}
Сразу создадим виджет на этот запрос (Counter):

Удалённые пользователи
Помните, мы не удаляли пользователей, а просто помечали их таковыми? Вот теперь это нам пригодится.
Запрос получается такой же, только меняем статус:
{
"collection": "users",
"query": {
"status": "deleted"
},
"count": true
}
Виджет создаётся точно так же, как в предыдущем запросе.
Все пользователи
Нам же интересно знать сумму всех пользователей бота? Думаю, да. Сделаем это:
{
"collection": "users",
"count": true
}
Запрос получился ещё проще, хех.
Сообщения
Количество элементов в коллекциях мы уже научились считать, давайте посчитаем сообщения:
{
"collection": "messages",
"count": true
}
Мы можем также захотеть видеть все наши сообщения в табличке, раз уж мы их сохраняем (а - анонимность):
{
"collection": "messages",
"aggregate": [
{
"$addFields": {
"datetime": {
"$toDate": {
"$multiply": [
"$datetime",
1000
]
}
}
}
}
]
}
Тут запрос уже посложнее. Давайте разбираться.
$toDate
ожидает миллисекунды, которые он преобразует в дату. Для этого мы должны сначала преобразовать наши секунды в виде Unix Timestamp в миллисекунды. Делаем это с помощью $multiply
— умножаем на 1000. После этих манипуляций $toDate
вернёт нам дату. Складываем её в столбец datetime
, который у нас уже есть (перезаписываем). Всё это позволяет нам сделать $addFields
(то же, что и $project
, только не стирает все существующие столбцы). Оборачиваем в aggregate
и запускаем.
Добавляем виджет таблички, где мы можем отключить ненужные нам столбцы, либо поменять их местами:

Ещё бы нам построить график, по которому будет видно, как изменяется активность по дням. Сделаем это:
{
"collection": "messages",
"aggregate": [
{
"$addFields": {
"datetime": {
"$toDate": {
"$multiply": [
"$datetime",
1000
]
}
}
}
},
{
"$group": {
"_id": {
"$dateToString": {
"format": "%Y-%m-%d",
"date": "$datetime"
}
},
"count": {
"$sum": 1
}
}
}
]
}
В этом запросе мы добавили группировку по столбцу datetime
в столбец _id
, в каждой группе хранится количество элементов благодаря count
.
Создаём график, где _id
— это ось Х, а count
— Y:

График пользователей
Фух, теперь самое важное — это график количества пользователей по дням. Меняем название коллекции у предыдущего запроса и получаем результат:
{
"collection": "users",
"aggregate": [
{
"$addFields": {
"datetime": {
"$toDate": {
"$multiply": [
"$datetime",
1000
]
}
}
}
},
{
"$group": {
"_id": {
"$dateToString": {
"format": "%Y-%m-%d",
"date": "$datetime"
}
},
"count": {
"$sum": 1
}
}
}
]
}

С запросами разобрались, осталось самое приятное — собрать дашборд.
Собираем дашборд
Все запросы, которые мы сделали, необходимо сохранить и дать им разумные названия. Также визуализацию, которую мы им давали, необходимо сохранить. После чего переходим на вкладку дашбордов, создаём новый и импортируем все виджеты поочередно:

На этом на сегодня всё :)