Анализ данных из постов Instagram*

* Instagram принадлежит компании Meta, признанной экстремистской и запрещенной на территории РФ.

В этом примере мы продемонстрируем, как можно проанализировать данные из датасета "instagram ads" на Kaggle. Данные в этом датасете представляют собой посты из социальной сети Instagram со всевозможными атрибутами (комментарии, лайки, информация об аудио и видео и прочее).

Загрузка исходных данных

Для начала загрузим данные. Это можно сделать либо в ручную через Мастер загрузки, либо с помощью, например, такого кода на Python.

Здесь мы задаем URL страницы датасета на Kaggle, проверяем, что скачанный файл является файлом .zip, и если это так, то распаковываем его содержимое во временную директорию, а затем загружаем в Tengri все распакованные файлы с помощью функции tngri.upload_file. Выводим информацию о них через print, чтобы получить имена загруженных файлов для их дальнейшего использования.

import urllib.request
import os
import zipfile
import tngri

zip_url = 'https://www.kaggle.com/api/v1/datasets/download/geraygench/instagram-ads'

urllib.request.urlretrieve(zip_url, 'data.zip')
temp_dir = 'temp'
try:
    with zipfile.ZipFile('data.zip', 'r') as zObject:
        zObject.extractall(path=temp_dir)
    for file in os.listdir(temp_dir):
        print(tngri.upload_file(os.path.join(temp_dir, file)))
except:
    print('Not a valid zip file')
<file_id>.json

Теперь скопируем имя сохраненного файла .json для вставки его в следующую ячейку в качестве аргумента функции read_json.

Выведем первые 5 строк загруженных данных, чтобы зрительно проверить, что загрузка прошла успешно. Для этого вставим имя файла, скопированное на предыдущем шаге.

SELECT * FROM read_json("<file_id>.json")
    LIMIT 5
Done in 1.1 sec
+-----------------------------------------------+---------------------+---------+-------------+-----+
| inputUrl                                      | id                  | type    | shortCode   | ... |
+-----------------------------------------------+---------------------+---------+-------------+-----+
| https://www.instagram.com/fjallravenofficial/ | 3351813129396710000 | Video   | C6ECEhTLlj7 | ... |
+-----------------------------------------------+---------------------+---------+-------------+-----+
| https://www.instagram.com/fjallravenofficial/ | 3335943316421300000 | Video   | C5LpsWOIUc8 | ... |
+-----------------------------------------------+---------------------+---------+-------------+-----+
| https://www.instagram.com/fjallravenofficial/ | 3319217982042080000 | Sidecar | C4QOysvtPUU | ... |
+-----------------------------------------------+---------------------+---------+-------------+-----+
| https://www.instagram.com/fjallravenofficial/ | 3372181927023210000 | Sidecar | C7MZZiWNffn | ... |
+-----------------------------------------------+---------------------+---------+-------------+-----+
| https://www.instagram.com/fjallravenofficial/ | 3369947094264730000 | Video   | C7EdQcJgkwr | ... |
+-----------------------------------------------+---------------------+---------+-------------+-----+

Теперь создадим таблицу instagram_post и загрузим в нее эти данные.

Для тех столбцов, в которых мы обнаружили вложенную структуру JSON, укажем тип JSON. Для некоторых столбцов укажем удобные нам новые имена и нужные типы данных (например, TIMESTAMP). Зададим ограничение, что значение идентификатора ig_post_id не должно быть пустым, чтобы отбросить потенциальные невалидные фрагменты данных.

CREATE OR REPLACE TABLE raw.instagram_post AS
SELECT
    inputUrl,
    id AS ig_post_id,
    type,
    shortCode, caption, hashtags, mentions, url,
    dimensionsHeight, dimensionsWidth,
    commentsCount ,	firstComment,
    displayUrl, images, videoUrl,
    alt, likesCount,
    videoViewCount, videoPlayCount,
    timestamp::TIMESTAMP AS post_ts,
    ownerFullName, ownerUsername, ownerId,
    productType,
    videoDuration,
    isSponsored, isPinned,
    locationName, locationId,
    error, description, paidPartnership,
    sponsors::JSON AS sponsors,
    taggedUsers::JSON AS taggedUsers,
    musicInfo::JSON AS musicInfo,
    coauthorProducers::JSON AS coauthorProducers,
    latestComments::JSON AS latestComments,
    childPosts::JSON AS childPosts
FROM read_json("<file_id>.json")
    WHERE ig_post_id IS NOT NULL;
Done in 1.7 sec
+--------+
| status |
+--------+
| CREATE |
+--------+

Выведем первые 5 строк таблицы, чтобы зрительно проверить, что данные в ней соответствуют нашим ожиданиям.

SELECT * FROM raw.instagram_post
    LIMIT 5;
Done in 1.2 sec
+-----------------------------------------------+---------------------+---------+-------------+-----+
| inputurl                                      | ig_post_id          | type    | shortcode   | ... |
+-----------------------------------------------+---------------------+---------+-------------+-----+
| https://www.instagram.com/fjallravenofficial/ | 3351813129396710000 | Video   | C6ECEhTLlj7 | ... |
+-----------------------------------------------+---------------------+---------+-------------+-----+
| https://www.instagram.com/fjallravenofficial/ | 3335943316421300000 | Video   | C5LpsWOIUc8 | ... |
+-----------------------------------------------+---------------------+---------+-------------+-----+
| https://www.instagram.com/fjallravenofficial/ | 3319217982042080000 | Sidecar | C4QOysvtPUU | ... |
+-----------------------------------------------+---------------------+---------+-------------+-----+
| https://www.instagram.com/fjallravenofficial/ | 3372181927023210000 | Sidecar | C7MZZiWNffn | ... |
+-----------------------------------------------+---------------------+---------+-------------+-----+
| https://www.instagram.com/fjallravenofficial/ | 3369947094264730000 | Video   | C7EdQcJgkwr | ... |
+-----------------------------------------------+---------------------+---------+-------------+-----+

Подготовка данных

Теперь проанализируем вложенную структуру JSON в столбце musicinfo, использовав для этого функции unnest и json_keys:

SELECT unnest(keys) AS musicinfo_keys, keys_count FROM
    (SELECT json_keys(musicinfo) AS keys, count(*) keys_count
        FROM raw.instagram_post WHERE musicinfo IS NOT NULL GROUP BY 1) t ;
Done in 1.1 sec
+--------------------------+------------+
| musicinfo_keys           | keys_count |
+--------------------------+------------+
| artist_name              | 1176       |
+--------------------------+------------+
| song_name                | 1176       |
+--------------------------+------------+
| uses_original_audio      | 1176       |
+--------------------------+------------+
| should_mute_audio        | 1176       |
+--------------------------+------------+
| should_mute_audio_reason | 1176       |
+--------------------------+------------+
| audio_id                 | 1176       |
+--------------------------+------------+

Извлечем данные из структуры JSON с помощью функции json_extract и запишем их в новую таблицу silver.instagram_musicinfo, столбцы которой — это ключи из исходной структуры JSON (внутри musicinfo), которые мы увидели на предыдущем шаге, а в столбец ig_post_id запишем id из исходной таблицы instagram_post.

Обратите внимание, что функцию json_extract мы используем здесь не более одного раза для одного столбца исходной таблицы. Это позволяет сэкономить время и вычислительные мощности, так как после однократного извлечения этих данных обращение к ним будет происходить практически моментально.
CREATE OR REPLACE TABLE silver.instagram_musicinfo AS
SELECT DISTINCT ig_post_id,
    arr[1] AS 'artist_name',
    arr[2] AS 'song_name',
    arr[3]::bool AS 'uses_original_audio',
    arr[4]::bool AS 'should_mute_audio',
    arr[5] AS 'should_mute_audio_reason',
    arr[6]::bigint AS 'audio_id'
FROM (SELECT ig_post_id, musicinfo,
    json_extract(musicinfo, ['artist_name',
                            'song_name',
                            'uses_original_audio',
                            'should_mute_audio',
                            'should_mute_audio_reason',
                            'audio_id'])
                            arr
    FROM raw.instagram_post WHERE musicinfo IS NOT NULL
) e;
Done in 1.1 sec
+--------+
| status |
+--------+
| CREATE |
+--------+

Выведем первые пять строк из получившейся таблицы, чтобы зрительно проверить данные в ней.

SELECT * FROM silver.instagram_musicinfo
    LIMIT 5;
Done in 1 sec
+---------------------+----------------------+---------------------------+---------------------+-------------------+--------------------------+------------------+
| ig_post_id          | artist_name          | song_name                 | uses_original_audio | should_mute_audio | should_mute_audio_reason | audio_id         |
+---------------------+----------------------+---------------------------+---------------------+-------------------+--------------------------+------------------+
| 3361389062866375005 | "fjallravenofficial" | "Original audio"          | true                | false             | ""                       | 1091589181917200 |
+---------------------+----------------------+---------------------------+---------------------+-------------------+--------------------------+------------------+
| 3362166784222944940 | "Lyle Workman"       | "Sun Beyond the Darkness" | false               | false             | ""                       | 700744903595866  |
+---------------------+----------------------+---------------------------+---------------------+-------------------+--------------------------+------------------+
| 3370702174072339576 | "victoriassecret"    | "Original audio"          | true                | false             | ""                       | 969258887793092  |
+---------------------+----------------------+---------------------------+---------------------+-------------------+--------------------------+------------------+
| 3365659145996406849 | "victoriassecret"    | "Original audio"          | true                | false             | ""                       | 1856092344873079 |
+---------------------+----------------------+---------------------------+---------------------+-------------------+--------------------------+------------------+
| 3367926439711140761 | "asos"               | "Original audio"          | true                | false             | ""                       | 1428332318047391 |
+---------------------+----------------------+---------------------------+---------------------+-------------------+--------------------------+------------------+

Теперь посмотрим на столбец исходной таблицы с информацией о затэганных пользователях taggedUsers. Обратим внимание, что в нем данные представлены в виде массивов. Используя функции unnest и json_extract, создадим таблицу silver.instagram_taggeduser:

CREATE OR REPLACE TABLE silver.instagram_taggeduser AS
    SELECT DISTINCT ig_post_id,
        arr[1]::varchar AS 'full_name',
        arr[2]::bigint AS 'user_id',
        arr[3]::bool AS 'is_verified',
        arr[4] AS 'profile_pic_url',
        arr[5] AS 'username'
    FROM (
        SELECT ig_post_id,
        json_extract(users, ['full_name',
                            'id','is_verified',
                            'profile_pic_url',
                            'username'])
        AS arr FROM
            (SELECT ig_post_id, unnest(json_extract(taggedUsers, '[*]'))
            AS users FROM
                raw.instagram_post WHERE taggedUsers IS NOT NULL
            ) un
        ) t;
Done in 1 sec
+--------+
| status |
+--------+
| CREATE |
+--------+

Выведем первые 5 строк созданной таблицы silver.instagram_taggeduser и визуально проверим данные в ней.

SELECT * FROM silver.instagram_taggeduser
    LIMIT 5;
Done in 1 sec
+---------------------+-------------------+-----------+-------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------+
| ig_post_id          | full_name         | user_id   | is_verified | profile_pic_url                                                                                                                                                                                                                                                                                                  | username           |
+---------------------+-------------------+-----------+-------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------+
| 3368467612563246843 | "Candice"         | 43114731  | true        | "https://scontent.cdninstagram.com/v/t51.2885-19/436426783_716232097252223_2080875243016028171_n.jpg?stp=dst-jpg_s150x150&_nc_ht=scontent.cdninstagram.com&_nc_cat=1&_nc_ohc=VZz3Y6G6kCgQ7kNvgEfJgX3&edm=APs17CUBAAAA&ccb=7-5&oh=00_AYDeE3YwxCQxVEK-3DLy0AK8cSmaFu3SVuwsUluh0pQ2Hg&oe=66526CB7&_nc_sid=10d13b"   | "candiceswanepoel" |
+---------------------+-------------------+-----------+-------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------+
| 3371457031159064630 | "Brittany Xavier" | 739181077 | true        | "https://scontent.cdninstagram.com/v/t51.2885-19/299498992_480162533527636_8112607220645623732_n.jpg?stp=dst-jpg_s150x150&_nc_ht=scontent.cdninstagram.com&_nc_cat=104&_nc_ohc=D83lh8W9o-EQ7kNvgEAZo1_&edm=APs17CUBAAAA&ccb=7-5&oh=00_AYCI_FerVMUvMEltLhAaANlfFdtezWw90dIOCff-oNuiLQ&oe=66526DD9&_nc_sid=10d13b" | "brittanyxavier"   |
+---------------------+-------------------+-----------+-------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------+
| 3350535229969664632 | "dev scudds"      | 200671402 | false       | "https://scontent.cdninstagram.com/v/t51.2885-19/316332449_539815587596795_7700370950656909913_n.jpg?stp=dst-jpg_s150x150&_nc_ht=scontent.cdninstagram.com&_nc_cat=111&_nc_ohc=yt51b9U7YQcQ7kNvgGr0PqA&edm=APs17CUBAAAA&ccb=7-5&oh=00_AYC_DbQKZ56A_C_kK4oCamtB10dpgXWxNr9dupqkTHIKZA&oe=665259D4&_nc_sid=10d13b" | "devscudds"        |
+---------------------+-------------------+-----------+-------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------+
| 3355576548572106408 | "Roxie Nafousi"   | 182064334 | true        | "https://scontent.cdninstagram.com/v/t51.2885-19/432688376_299228906523099_7608649815950644359_n.jpg?stp=dst-jpg_s150x150&_nc_ht=scontent.cdninstagram.com&_nc_cat=1&_nc_ohc=mNDTJLE0sakQ7kNvgFoinRd&edm=APs17CUBAAAA&ccb=7-5&oh=00_AYDyLDXyYkSqF7jeJ7SDKO-ATM7WbbH8OYqhw_GOjiGygQ&oe=66526921&_nc_sid=10d13b"   | "roxienafousi"     |
+---------------------+-------------------+-----------+-------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------+
| 3369046462609537802 | "ASOS MAN"        | 640874843 | true        | "https://scontent.cdninstagram.com/v/t51.2885-19/244277018_902025494057602_3929487210907869376_n.jpg?stp=dst-jpg_s150x150&_nc_ht=scontent.cdninstagram.com&_nc_cat=110&_nc_ohc=5aRpL0ZaRW8Q7kNvgFG0_9g&edm=APs17CUBAAAA&ccb=7-5&oh=00_AYBmZ6qVQtwRziMSsl8tGtlX7u4-RnYXa-MxQIaIEKyc7Q&oe=66527A51&_nc_sid=10d13b" | "asos_man"         |
+---------------------+-------------------+-----------+-------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------+

Теперь посмотрим на столбец исходной таблицы с информацией о комментариях latestComments. В нем данные представлены в виде массива комментариев. Чтобы узнать, какие ключи встречаются внутри этих массивов, используем функции unnest, json_keys и json_extract и выполним такой запрос:

SELECT unnest(keys) AS comment_keys FROM
    (SELECT json_keys(comments) AS keys, count(*) FROM
        (SELECT ig_post_id, unnest(json_extract(latestComments, '[*]'))
        AS comments FROM
            raw.instagram_post WHERE latestComments IS NOT NULL) un GROUP BY 1) t;
Done in 1 sec
+--------------------+
| comment_keys       |
+--------------------+
| id                 |
+--------------------+
| text               |
+--------------------+
| ownerUsername      |
+--------------------+
| ownerProfilePicUrl |
+--------------------+
| timestamp          |
+--------------------+
| likesCount         |
+--------------------+
| repliesCount       |
+--------------------+
| replies            |
+--------------------+

Извлечем комментарии в таблицу silver.instagram_comments аналогичным образом, как мы это сделали выше для пользователей и исполнителей.

Обратим внимание, что в этой таблице likesCount и repliesCount — это количество лайков и ответов на данный комментарий (а не на исходный пост).

CREATE OR REPLACE TABLE silver.instagram_comments as
    SELECT DISTINCT ig_post_id,
        arr[1]::bigint AS comment_id,
        arr[2] AS 'text',
        arr[3] AS 'ownerUsername',
        arr[4] AS 'ownerProfilePicUrl',
        arr[5]::timestamp AS 'comment_ts',
        arr[6]::int AS 'likesCount',
        arr[7]::int AS 'repliesCount',
        arr[8] AS 'replies'
FROM (
SELECT ig_post_id,
    json_extract(comments, ['id','text','ownerUsername','ownerProfilePicUrl',
    'timestamp','likesCount','repliesCount','replies']) AS arr
    FROM (SELECT ig_post_id, unnest(json_extract(latestComments, '[*]')) AS comments
        FROM raw.instagram_post WHERE latestComments IS NOT NULL) un ) t;
Done in 1 sec
+--------+
| status |
+--------+
| CREATE |
+--------+

Проверим получившуюся таблицу:

SELECT * FROM silver.instagram_comments
    LIMIT 5;
Done in 1 sec
+---------------------+-------------------+--------------------------------------------------------------------+----------------------------------+-----+
| ig_post_id          | comment_id        | text                                                               | ownerusername                    | ... |
+---------------------+-------------------+--------------------------------------------------------------------+----------------------------------+-----+
| 3351813129396705531 | 18025641284105656 | "Your work apron is cool..\nDo Fjalraven sell them to the public?" | "dai_stick"                      | ... |
+---------------------+-------------------+--------------------------------------------------------------------+----------------------------------+-----+
| 3367108632665594085 | 18010752380180096 | "Well done 👏"                                                      | "alpencore"                      | ... |
+---------------------+-------------------+--------------------------------------------------------------------+----------------------------------+-----+
| 3362086677098626407 | 18041534590828292 | "Still made in cheap labour countries"                             | "leineleineleineleineleineleine" | ... |
+---------------------+-------------------+--------------------------------------------------------------------+----------------------------------+-----+
| 3362086677098626407 | 18028710974031364 | "🔥🔥🙌"                                                              | "arifwidie26"                    | ... |
+---------------------+-------------------+--------------------------------------------------------------------+----------------------------------+-----+
| 3361389062866375005 | 18012200105461376 | "Classic description of “type 2 fun”"                              | "itskate_g"                      | ... |
+---------------------+-------------------+--------------------------------------------------------------------+----------------------------------+-----+

Результат 1: Популярность исполнителей

Теперь используем собранные выше данные, чтобы построить таблицу, в которой каждая строка соответствует одному исполнителю, а в столбцах представлена различная информация, так или иначе свидетельствующая о популярности этого исполнителя:

  • songs — количество композиций данного исполнителя

  • ig_posts — количество постов с композициями данного исполнителя

  • comments — количество комментариев в постах с композициями данного исполнителя

  • tagged_users — количество затэганных пользователей в постах с композициями данного исполнителя

  • likesCount — количество лайков в постах с композициями данного исполнителя

  • repliesCount — количество реплаев в постах с композициями данного исполнителя

Для этого используем выражение LEFT JOIN.

Упорядочим финальную таблицу по третьему столбцу (ig_posts) по убыванию.

SELECT artist_name,
    count(distinct song_name) AS songs,
    count(distinct im.ig_post_id) AS ig_posts,
    count(distinct comment_id) AS comments,
    count(distinct user_id) AS tagged_users,
    sum(likesCount) AS likesCount,
    sum(repliesCount) AS repliesCount
FROM silver.instagram_musicinfo im
    LEFT JOIN silver.instagram_taggeduser tu ON tu.ig_post_id=im.ig_post_id
    LEFT JOIN silver.instagram_comments ic ON ic.ig_post_id =im.ig_post_id
GROUP BY 1 ORDER BY 3 DESC;
Done in 1.6 sec
+-------------------+-------+----------+----------+--------------+------------+--------------+
| artist_name       | songs | ig_posts | comments | tagged_users | likescount | repliescount |
+-------------------+-------+----------+----------+--------------+------------+--------------+
| "telfarglobal"    | 9     | 136      | 985      | 120          | 634        | 156          |
+-------------------+-------+----------+----------+--------------+------------+--------------+
| "everlane"        | 1     | 95       | 532      | 6            | 513        | 65           |
+-------------------+-------+----------+----------+--------------+------------+--------------+
| "asos"            | 3     | 93       | 503      | 60           | 583        | 85           |
+-------------------+-------+----------+----------+--------------+------------+--------------+
| "victoriassecret" | 1     | 83       | 686      | 49           | 185        | 16           |
+-------------------+-------+----------+----------+--------------+------------+--------------+
| "summerfridays"   | 2     | 65       | 574      | 48           | 173        | 18           |
+-------------------+-------+----------+----------+--------------+------------+--------------+
| ...               | ...   | ...      | ...      | ...          | ...        | ...          |
+-------------------+-------+----------+----------+--------------+------------+--------------+

Эту таблицу можно сохранить в формат .xlsx, нажав на кнопку Download output as XLSX на данной ячейке. После этого в любом приложении для просмотра файлов .xlsx можно упорядочить собранные данные по любому столбцу, наложить дополнительные фильтры, скопировать данные или их часть для вставки в аналитические отчеты.

Сохраненный таким образом файл можно скачать здесь.

Результат 2: Распределение комментариев и событий в них во времени

Проанализируем распределение комментариев и событий в них (лайков и реплаев) в зависимости от времени, прошедшего от публикации поста до публикации данного комментария к нему — "свежести" комментария относительно поста, к которому он относится.

Для этого построим таблицу, в которой каждая строка будет соответствовать всем таким парам "пост — комментарий к нему", что между ними прошло 0 дней, 1 день и так далее до 9. И для всех таких пар выведем в столбцы:

  • comments — количество таких комментариев

  • likescount — количество лайков у таких комментариев

  • repliescount — количество реплаев у таких комментариев

SELECT
    (comment_ts::DATE - post_ts::DATE)::INT AS days_till_comment,
    count(DISTINCT comment_id) AS comments,
    sum(c.likesCount)::int AS likesCount,
    sum(c.repliesCount)::int AS repliesCount
FROM raw.instagram_post p
LEFT JOIN silver.instagram_comments c  on p.ig_post_id=c.ig_post_id
GROUP BY 1 ORDER BY 1 LIMIT 10;
Done in 1.7 sec
+-------------------+----------+------------+--------------+
| days_till_comment | comments | likescount | repliescount |
+-------------------+----------+------------+--------------+
| 0                 | 2876     | 1926       | 614          |
+-------------------+----------+------------+--------------+
| 1                 | 3288     | 1847       | 460          |
+-------------------+----------+------------+--------------+
| 2                 | 1980     | 830        | 189          |
+-------------------+----------+------------+--------------+
| 3                 | 1352     | 635        | 102          |
+-------------------+----------+------------+--------------+
| 4                 | 841      | 288        | 46           |
+-------------------+----------+------------+--------------+
| 5                 | 610      | 230        | 26           |
+-------------------+----------+------------+--------------+
| 6                 | 516      | 103        | 37           |
+-------------------+----------+------------+--------------+
| 7                 | 411      | 88         | 26           |
+-------------------+----------+------------+--------------+
| 8                 | 299      | 75         | 17           |
+-------------------+----------+------------+--------------+
| 9                 | 249      | 96         | 17           |
+-------------------+----------+------------+--------------+

Теперь в ячейке типа Python построим график по данным из этой таблицы. Для этого воспользуемся модулем Python matplotlib. Чтобы взять данные из предыдущей ячейки, используем переменную cell_output.

import matplotlib

plt = cell_output.plot(
    title='Распределение комментариев и событий в них',
    y=[
        'comments',
        'likescount',
        'repliescount',
    ],
    label = ['Комментариев', 'Лайков к комментарию', 'Реплаев к комментарию'],
    ylabel='Количество',
    x='days_till_comment',
    xlabel = 'Дней между постом и комментарием',
    figsize=(10,5),
)
plt.set_xticks(cell_output['days_till_comment'])
plt.get_figure()
instagram example result 2

На графике хорошо видно, что количество комментариев к посту в первый день возрастает, а потом плавно снижается. Также видно, каким образом снижается активность внутри самих комментариев (лайки и реплаи к комментариям) в зависимости от устаревания комментария относительно даты поста.