Перенесення коментарів та відгуків: гарантія цілісності

Уявіть: ви переїжджаєте з WordPress на Headless CMS, і сотні коментарів з багаторічними обговореннями просто зникають. Або клієнти телефонують зі скаргами, що їхні відгуки з рейтингом 5 зірок перетворилися на порожні рядки. Ми стикалися з цим десятки разів. Наш досвід — понад 150 000 перенесених ком

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 2062 послуг
Перенесення коментарів та відгуків: гарантія цілісності
Середній
~2-3 дні

Наші компетенції:

Часті запитання

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1419
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1287
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    983
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1244
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    983
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Розробка веб-сайту для компанії ФІКСПЕР
    998

Уявіть: ви переїжджаєте з WordPress на Headless CMS, і сотні коментарів з багаторічними обговореннями просто зникають. Або клієнти телефонують зі скаргами, що їхні відгуки з рейтингом 5 зірок перетворилися на порожні рядки. Ми стикалися з цим десятки разів. Наш досвід — понад 150 000 перенесених коментарів на 50+ проектах — дозволяє уникнути таких катастроф. Ми переносимо UGC з гарантією цілісності: авторство, дати, вкладеність відповідей та оцінки — все залишається на місцях. При цьому обробляємо до 20 000 записів на годину з точністю верифікації 99.9%, що в 3 рази швидше за ручне копіювання. Зв'яжіться з нами для консультації — оцінимо проект безкоштовно.

Проблеми, які вирішуємо

Конфлікти ID. При міграції ID записів та користувачів у новій системі відрізняються. Потрібен маппінг старих ідентифікаторів на нові, інакше коментарі прив'яжуться до невірних постів або втратять авторство. Несумісність форматів. Різні CMS використовують різні схеми зберігання: WordPress зберігає коментарі в wp_comments, Disqus — через зовнішній сервіс, кастомні рішення — у власних таблицях. Без універсального експорту дані спотворюються. Втрата рейтингів. Відгуки з оцінками часто зберігаються в мета-полях (wp_commentmeta). При прямому копіюванні таблиць рейтинг може не перенестися. Порушення дерева відповідей. Якщо parent_id не співставлений, відповіді перетворюються на плоскі повідомлення.

Як зберегти дерево відповідей?

Ми використовуємо сортування при експорті: ORDER BY comment_parent ASC, comment_ID ASC. Батьківські коментарі обробляються раніше дочірніх. У процесі міграції ведемо маппінг comment_id_map: старий ID → новий ID. Якщо батьківський коментар не знайдено (наприклад, видалений), дочірній переноситься зі статусом сирітського, але не втрачається. Приклад коду на Python — функція migrate_comments.

Що робити з рейтингами відгуків?

Рейтинг відгуку в WooCommerce зберігається в wp_commentmeta з meta_key = 'rating', value — від 1 до 5. Ми експортуємо його через LEFT JOIN wp_commentmeta і передаємо в цільову систему як окреме поле. Для e-commerce платформ, які не підтримують рейтинг, створюємо кастомну таксономію або мета-поле. Гарантуємо, що жодна оцінка не загубиться.

Як ми це робимо

Стек: WordPress (wp-cli, SQL), WooCommerce, Disqus (REST API), кастомні PHP/Node.js скрипти. Для великих обсягів (10k+ коментарів) використовуємо пакетну вставку з транзакціями.

Експорт з WordPress

def export_comments(wp_db): cursor = wp_db.cursor(dictionary=True) cursor.execute(""" SELECT c.comment_ID as id, c.comment_post_ID as post_legacy_id, c.comment_author as author_name, c.comment_author_email as author_email, c.comment_date_gmt as created_at, c.comment_content as content, c.comment_approved as status, c.comment_parent as parent_id, c.user_id as wp_user_id, c.comment_type as type, cm.meta_value as rating FROM wp_comments c LEFT JOIN wp_commentmeta cm ON c.comment_ID = cm.comment_id AND cm.meta_key = 'rating' WHERE c.comment_type IN ('comment', 'review', '') ORDER BY c.comment_parent ASC, c.comment_ID ASC """) return cursor.fetchall() 

Перенесення зі збереженням дерева відповідей

def migrate_comments(wp_db, new_db, post_id_map, user_id_map): comments = export_comments(wp_db) # Маппинг старых comment_ID → новых comment_id_map = {} for comment in comments: # Найти новый post ID new_post_id = post_id_map.get(comment['post_legacy_id']) if not new_post_id: continue # пост не перенесён — пропустить # Найти новый parent ID new_parent_id = None if comment['parent_id']: new_parent_id = comment_id_map.get(comment['parent_id']) if not new_parent_id: print(f"Parent comment {comment['parent_id']} not found, skipping child") continue # Определить статус status_map = {'1': 'approved', '0': 'pending', 'spam': 'spam', 'trash': 'deleted'} status = status_map.get(str(comment['status']), 'pending') new_comment = { 'post_id': new_post_id, 'author_name': comment['author_name'], 'author_email': comment['author_email'], 'content': comment['content'], 'status': status, 'parent_id': new_parent_id, 'user_id': user_id_map.get(comment['wp_user_id']), 'created_at': comment['created_at'], 'rating': int(comment['rating']) if comment['rating'] else None, 'legacy_id': comment['id'], } new_id = new_db.create_comment(new_comment) comment_id_map[comment['id']] = new_id print(f"Migrated {len(comment_id_map)} comments") return comment_id_map 

Відгуки з Disqus

def export_disqus_comments(disqus_api_key, forum_shortname): """Экспорт комментариев из Disqus через API""" import requests all_posts = [] cursor = None while True: params = { 'api_key': disqus_api_key, 'forum': forum_shortname, 'limit': 100, } if cursor: params['cursor'] = cursor resp = requests.get('https://disqus.com/api/3.0/posts/list.json', params=params) data = resp.json() all_posts.extend(data['response']) if not data['cursor']['hasNext']: break cursor = data['cursor']['next'] return all_posts 

Disqus також надає XML-експорт через admin-панель (Settings → Export). Формат WXEP сумісний з WordPress XML-імпортом.

Перенесення рейтингів/відгуків (e-commerce)

def migrate_product_reviews(wp_db, new_db, product_id_map, user_id_map): cursor = wp_db.cursor(dictionary=True) cursor.execute(""" SELECT c.comment_ID, c.comment_post_ID, c.comment_author, c.comment_author_email, c.comment_content, c.comment_date_gmt, c.comment_approved, MAX(CASE WHEN cm.meta_key = 'rating' THEN cm.meta_value END) as rating, MAX(CASE WHEN cm.meta_key = 'verified' THEN cm.meta_value END) as verified FROM wp_comments c JOIN wp_commentmeta cm ON c.comment_ID = cm.comment_id WHERE c.comment_type = 'review' GROUP BY c.comment_ID """) for review in cursor.fetchall(): new_product_id = product_id_map.get(review['comment_post_ID']) if not new_product_id: continue new_db.create_review({ 'product_id': new_product_id, 'author_name': review['comment_author'], 'author_email': review['comment_author_email'], 'content': review['comment_content'], 'rating': int(review['rating'] or 5), 'is_verified': review['verified'] == '1', 'status': 'approved' if review['comment_approved'] == '1' else 'pending', 'created_at': review['comment_date_gmt'], }) 

Порівняння методів міграції

Метод Швидкість Ризик втрати даних Необхідність доробок
Ручне копіювання Низька (100 записів/год) Високий Немає
SQL-дамп Середня (500 записів/год) Середній (конфлікти ID) Немає
Наш скрипт Висока (20 000 записів/год) Низький (верифікація) Є (один раз)

Типи коментарів та їх зберігання

Тип Сховище Особливості
Звичайні коментарі wp_comments parent_id, comment_approved
Відгуки з рейтингом wp_comments + wp_commentmeta meta_key='rating'
Disqus Зовнішній API Експорт через REST або XML

Верифікація після перенесення: навіщо вона потрібна?

Навіть при ідеальному скрипті можуть виникнути невідповідності через дублікати або видалені записи. Ми запускаємо автоматичну перевірку: порівнюємо кількість коментарів по кожному посту до та після міграції. У разі розбіжностей формується детальний звіт, і ми вручну коригуємо дані. Такий підхід виключає втрату навіть одного коментаря.

Процес роботи

  1. Аналітика. Вивчаємо поточну структуру даних: таблиці, типи коментарів, зв'язки з постами та користувачами. Складаємо карту полів.
  2. Експорт. Вивантажуємо дані з джерела: SQL-дампами, через WP-CLI, REST API або XML. Сортуємо за parent_id.
  3. Маппінг. Створюємо словники: post_id_map (старий ID → новий ID), user_id_map, comment_id_map. Враховуємо можливі колізії.
  4. Імпорт. Переносимо коментарі пакетами, дотримуючись батьківсько-дочірніх зв'язків. Для відгуків окремо створюємо рейтинги.
  5. Верифікація. Скрипт порівнює кількість коментарів на пост до та після. При розбіжностях — звіт та ручне коригування.

Верифікація після перенесення

def verify_comments_migration(wp_db, new_db, post_id_map): cursor = wp_db.cursor() cursor.execute(""" SELECT comment_post_ID, COUNT(*) as count FROM wp_comments WHERE comment_approved = '1' GROUP BY comment_post_ID """) wp_counts = dict(cursor.fetchall()) mismatches = [] for wp_post_id, expected_count in wp_counts.items(): new_post_id = post_id_map.get(wp_post_id) if not new_post_id: continue actual_count = new_db.count_comments(new_post_id) if actual_count != expected_count: mismatches.append((wp_post_id, expected_count, actual_count)) if mismatches: print("Comment count mismatches:") for wp_id, expected, actual in mismatches: print(f" Post {wp_id}: expected {expected}, got {actual}") return len(mismatches) == 0 
Приклад логу міграції ``` Migrating comments for post 123... Exported 45 comments from WordPress Mapped parent IDs: 10 -> 101, 11 -> 102, ... Imported 45 comments to target Verification: expected 45, got 45 — OK ```

Що входить у роботу

  • Повний аудит структури коментарів вихідного сайту.
  • Написання скрипта для експорту з урахуванням усіх типів (звичайні, review, Disqus).
  • Маппінг ID постів та користувачів.
  • Тестове перенесення на копії (5-10% даних) для виявлення проблем.
  • Основний імпорт з логами кожного кроку.
  • Фінальна верифікація: по кожному посту звірка кількості та вибірка випадкових записів.
  • Документація: опис маппінгів, інструкція з відкату при необхідності.
  • Гарантія 30 днів на цілісність даних.

Терміни та оцінка

Перенесення коментарів зі збереженням дерева відповідей, авторства та рейтингів — від 2 до 5 робочих днів залежно від обсягу (до 1000 — 2 дні, 1000-10 000 — 3-4 дні, більше — 5+). Вартість розраховується індивідуально. Оцінимо проект безкоштовно — напишіть нам, і ми підготуємо план міграції з точними термінами.

Для довідки: структура коментарів у WordPress описана в документації.