Проблема с постоянными ссылками после миграции

Привет!

Мне удалось успешно мигрировать старую самодельную форумную программу в Discourse.
После 24-часового импорта 2 миллионов записей всё работает как по маслу, за исключением постоянных ссылок.

В таблице permalinks базы данных Discourse у меня около 350 000 постоянных ссылок. Все они в нижнем регистре, например: “forum/t140842-s1/8p-hilfe-bei-1-8-tfsi-guter-motor-oder-schlechter-motor.html”.

К сожалению, Google ссылается на “/forum/t140842/8P-Hilfe-bei-1-8-tfsi-guter-Motor-oder-schlechter-Motor/”, и я получаю ошибку 404. :frowning:

Подскажите, пожалуйста, как можно привести запрашиваемый URL к нижнему регистру перед поиском в таблице permalinks, не сломав при этом что-либо другое? Разве такое преобразование перед поиском не должно быть стандартным?

Спасибо за отличное программное обеспечение!

Гёкс

Добро пожаловать! Поздравляем с тем, что вы дошли до этого этапа!

Вы хотите создать нормализацию постоянных ссылок, которая отбрасывает слаг и формирует ссылки, содержащие только идентификатор форума, верно?

Для определения нужной темы достаточно t140842-s1, не так ли?

Существуют и другие импортеры, которые делают подобное, хотя я не уверен, какие именно. Возможно, vBulletin? Но если вы выполните поиск по всем импортерам с помощью grep по слову «normalization», то наверняка найдёте мой пример.

Спасибо за быстрый ответ.

До миграции я не знал, что поиск учитывает регистр — иначе я бы учёл это и убедился, что URL сохраняется так же, как в старом программном обеспечении.

Но миграция уже завершена, и сайт работает в продуктивной среде. К сожалению, мне теперь нужно искать обходные пути.

Я могу идентифицировать тему по её ID, поэтому «/forum/t140842» было бы достаточно. Через SQL я мог бы изменить поле url в таблице permalinks таким образом, но будет ли тогда выполняться поиск и перенаправление? Я провёл быстрое тестирование, и это не сработало.

В настройках Discourse есть опция нормализации постоянных ссылок, но я не до конца понял, что именно она делает.

Нормализация постоянных ссылок изменит URL перед его сопоставлением с постоянной ссылкой, поэтому вы можете использовать её для удаления слага. Описание этой функции в настройках её объясняет, но, возможно, только если вы уже её понимаете. :man_shrugging:

Старые идентификаторы тем должны находиться в поле topicCustomField, поэтому вы сможете создать новые постоянные ссылки, перебирая их. Затем просто удалите старые. (или удалите все из них, когда убедитесь, что сможете создать нужные вам).

Вы можете искать здесь и в других импортерах по ключевым словам «permalink» и «normalization», чтобы найти примеры (один из способов — grep -r). Если вам нужна дополнительная помощь и у вас есть бюджет, я могу помочь на следующей неделе.

Хорошо, у меня есть такой запрос:

https://a3-freunde.de/forum/t140842/8P-Hilfe-bei-1-8-tfsi-guter-Motor-oder-schlechter-Motor

и одна нормализация постоянных ссылок в конфигурации, например:

/t(\d*)/?$forum/t\1

которая должна приводить к “forum/t140842” для вышеуказанного запроса.

Когда я добавляю URL “forum/t140842” в таблицу постоянных ссылок Discourse, это не даёт никакого эффекта?
Верны ли мои предположения? Что я упускаю?

Вы на правильном пути. Регулярные выражения могут быть капризными. Думаю, вам нужно добавить forum/ в начало вашего постоянного URL.

Спасибо за усилия. Я ценю это.

В конфигурации я изменил свой регулярный выражение на (я имею в виду, что мой должен также сопоставлять ID темы):

forum/t(\d*)/?$forum/t\1

Когда я добавляю новую постоянную ссылку в таблицу с URL “forum/t140842” и сохраняю её… Discourse меняет URL на “f?$forum/t140842”. Либо это ошибка, либо я не понимаю концепцию здесь.

:confused:

После дополнительных попыток нормализации с помощью регулярных выражений мне не удалось понять, как это работает.
Использование примера из описания снова привело к неожиданным результатам в поле URL при добавлении новых постоянных ссылок.

При миграции на Discourse я убрал префикс www из домена.
Это дало мне возможность переписать URI на старом сервере через конфигурацию Apache и файл .htaccess, приведя его к нижнему регистру, прежде чем перенаправлять на новый сервер Discourse. Пока что это частично решило мою проблему.

Не сработало как ожидалось, потому что часть URL (slug) была сгенерирована в скрипте миграции немного иначе, чем в старом программном обеспечении.

Поэтому я «нормализовал» URL самостоятельно.

Добавление/генерация нормализованных URL (таблица пермалинков Discourse)

В поле URL преобразуйте:

forum/t140842-s1/8p-hilfe-bei-1-8-tfsi-guter-motor-oder-schlechter-motor.html

или

forum/t140842-s2/8p-hilfe-bei-1-8-tfsi-guter-motor-oder-schlechter-motor.html

или

forum/t140842/8p-hilfe-bei-1-8-tfsi-guter-motor-oder-schlechter-motor.html

в простой URL, содержащий только ID старой темы:
forum/t140842

Это выполняется с помощью SQL-команды, которая переписывает URL с помощью функции REGEXP_REPLACE:

INSERT INTO permalinks (created_at, updated_at, topic_id, url) SELECT NOW(), NOW(), topic_id, REGEXP_REPLACE(url,'forum/t(\d*)(-?.*)/(.*)','forum/t\1','') url FROM permalinks WHERE topic_id > 0 ON CONFLICT DO NOTHING;

Переписывание старых запросов через .htaccess на старом домене

RewriteRule ^forum/t([0-9]*)(-?.*)/(.*)$ https://discourse-domain.com/forum/t$1 [R=301,L]

Что здесь происходит?

Google проиндексировал и ссылается на URL https://old-domain.com/forum/t140842/8p-hilfe-bei-1-8-tfsi-guter-motor-oder-schlechter-motor.html. Мне повезло, что этот запрос попал на сервер Apache из-за другого домена, поэтому я мог легко использовать .htaccess для переписывания. Таким образом, я переписываю этот запрос в https://discourse-domain.com/forum/t140842. В таблицу пермалинков я добавил запись forum/t140842, используя уже существующий пермалинк с полным URL (с слагом), применив регулярное выражение (см. выше).

Надеюсь, это поможет кому-то другому как отправная точка.