迁移后固定链接出现问题

你好,

我成功地将一个自行编写的旧版论坛软件迁移到了 Discourse。
在导入了 200 万条记录并运行 24 小时后,除了永久链接(permalinks)之外,一切运行完美。

我在 Discourse 的 permalinks 数据库表中大约有 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:

有什么建议可以在查询 permalinks 表之前将请求 URL 转换为小写,同时不破坏其他功能吗?难道这种在查找前进行的转换不应该成为标准做法吗?

感谢你们开发了如此出色的软件!

Göks

欢迎!恭喜您走到这一步!

您想创建一个规范化永久链接的规则,去掉 slug,仅使用论坛 ID 来生成永久链接,我猜是这样。

要识别正确的主题,只需要 t140842-s1 对吧?

确实有一些其他导入器也这样做,不过我不确定具体是哪些。也许是 vBulletin?但如果您对所有导入器进行规范化相关的 grep 搜索,应该能找到我的示例。

1 个赞

感谢您的快速回复。

在迁移之前,我并不知道查找操作是区分大小写的——否则我会提前考虑到这一点,并确保 URL 的保存方式与旧软件中一致。

不过现在迁移已经完成,站点也已正式投入使用。因此,我目前只能寻找变通方案。

我可以通过主题 ID 来识别主题,因此像“/forum/t140842”这样的路径就足够了。通过 SQL,我可以按这种方式修改 permalinks 表中的 url 字段,但这样之后是否还能正常查找并重定向?我快速测试了一下,发现不行。

Discourse 设置中有一个关于 permalinks 规范化的选项,但我不太清楚它的具体作用。

规范化永久链接会在匹配永久链接之前重写 URL,因此你可以用它来移除 slug。设置中的说明解释了这一点,但可能只有在你已经理解的情况下才能看懂。:man_shrugging:

旧的主题 ID 应位于 topicCustomField 中,因此你可以通过遍历这些 ID 来创建新的永久链接。然后只需删除旧的链接(或者在你确信能够生成所需链接后,删除所有旧链接)。

你可以在这里以及其他导入器中搜索“永久链接”和“规范化”以找到一些示例(grep -r 是一种方法)。如果你需要更多帮助且有预算,我可以在下周协助你。

1 个赞

好的,我有一个请求:

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/

感谢付出,我很感激。

在配置中,我将我的正则表达式改为(我的意思是它应该也能匹配主题 ID):

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

当我在表中添加一条新永久链接,URL 为 “forum/t140842” 并保存后……Discourse 将 URL 更改为 “f?$forum/t140842”。这要么是一个 bug,要么是我没有理解这里的概念。

:confused:

在进一步尝试正则表达式规范化后,我仍无法弄清楚其工作原理。使用描述中的示例在添加新永久链接时,再次导致 URL 字段出现意外结果。

迁移到 Discourse 时,我移除了域名的 www 前缀。这使我现在有机会通过 Apache 配置和 .htaccess 在旧服务器上重写 URI 为小写,然后再重定向到新的 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

转换为仅包含旧主题 ID 的简单 URL:

forum/t140842

这是通过一条 SQL 命令完成的,该命令使用 REGEXP_REPLACE 函数重写 URL:

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。我在 permalinks 表中添加了 forum/t140842 这条记录,方法是利用已添加的包含完整 slug 的永久链接,并通过正则表达式进行处理(见上文)。

希望这能作为起点帮助到其他人。

1 个赞