从 LeanCloud 迁移 Waline 评论数据至 MongoDB (详细版)

今日在升级站点主题版本时,偶然进入了站点的 Waline 评论管理后台。却惊闻 LeanCloud 即将于停止服务(DDL:2027-01)1

根据 Waline 相关文档2,博主选择了 MongoDB 进行迁移,其提供了具有免费的 512M 存储,且格式与 LeanCloud 导出格式兼容。

然而博主以前没有使用过 MongoDB 服务,虽然最后成功了,但在迁移过程中还是有一些磕磕绊绊的地方。故写此文,出一个详细教程,分享给有需要的小白用户。

数据导出

这里,你也可以选择使用 Waline 后台自带的导出功能,得到一个 json 文件。这样做的好处是,不必去纠结底层数据结构,Waline 会自动进行对应的读取和写入操作。但是,如果数据量较大,此方法可能由于网络/并发等因素失败。另外,在迁移到新平台导入数据时,你可能需要重新在 Waline 系统注册一个账户(并作为管理员),才能登录后台将数据导入;完成导入后,可能需要手动删除临时用户。

出于以上种种考虑,本文还是选择在数据库底层进行操作,这样在应用层可以实现无缝迁移。

首先前往 LeanCloud 并登录控制台。我们前往 数据存储 --> 导入导出 ,这里我们选择备份导出,因为它能够导出 MongoDB 可直接导入的 BSON 格式。如图所示,我们只需要勾选 CommentCounterUsers

LeanCloud 导出

导出后,数据默认会发送到邮箱,且为gz 格式。将他们下载并放入一个文件夹中,这里我放在了 111 文件夹,这个路径后续要用到。

导出后的文件

MongoDB 注册与配置

MongoDB 官网为:https://www.mongodb.com,前去输入邮箱,完成邮箱验证即可注册。

为了方便后面理解,在这里我们了解下 MongoDB 的常用概念:

  1. Cluster (集群)运行环境。你可以把它理解为安装了 MongoDB 的服务器(或服务器组)。
  2. Database (数据库)数据仓库。一个集群里可以放多个独立的数据库,用来区分不同的项目。
  3. Collection (集合)分类文件夹。在数据库里把数据分类存放,对应传统数据库的“表”。
  4. Document (文档)具体数据。集合里的一条条记录,采用类 JSON 的格式存储。

用代码块绘制一下大概这样:

1
2
3
4
5
6
7
8
9
10
11
12
Cluster (集群)
|
|-- Database: "Shop" (数据库)
| |-- Collection: "Users" (集合)
| | |-- Document 1 (文档)
| | |-- Document 2 (文档)
| |
| |-- Collection: "Orders" (集合)
| |-- Document 1 (文档)
|
|-- Database: "Blog" (数据库)
|-- Collection: "Posts" (集合)

新建 Cluster

完成注册后,新建一个 Cluster(在此之前可能会要求新建 Project,名字随意),Cluster 的命名可以根据喜好来,我这里用的是 waline-hui-shao,不过我推荐保留 Cluster 字样,以免一会儿把自己绕晕了。

按下图进行配置,选择”免费计划“,供应商选择”AWS“,地区更改为香港,这样速度比较快。我这里因为已经建好了,所以是编辑页面。

Cluster 配置

新建用户

随后,我们转到 Database & Network Access - Database Users,新建用户。首先建立第一个用户,他默认具有 Cluster 的全部管理权限。建议命名为 xxxAdmin 这样的,方便区分,记得设置一个强密码。

新建 admin 用户

根据最小权限原则,我们应该给 Waline 再建立个用户,让他只对特定数据库有读写权限。在此之前,我们要先设置个权限模板。转到同一页面上的 Custom Roles,新建一个角色。

Custom Roles

给权限模板起个名字,这里我的是 walineDatabaseRW,随后,按图中方式,授予单一数据库(数据库名为 waline)的读写权限。

Role 权限设置 1
Role 权限设置 2

随后,我们回到 Database Users 这里,再新建个用户,这次我们要建立的是普通用户,我起名为 waline_user,密码请自行设置个不一样的,假定为 waline_user_passwd

权限方面,需要按下图进行配置,设置 Custom Roles 为我们刚刚新建的,注意把默认分配的 admin 角色删除掉。

新建普通用户

网络访问权限

建立完成普通用户后,接下来进行网络访问配置。MongoDB 默认是不允许外部访问的,我们需要开放 IP 白名单。转到同一页面的 IP Access List,新增记录,输入 CIDR 0.0.0.0/0,放开所有 IP 访问,如下图。

这里,由于我的服务端运行在 Vercel,IP 可能不确定,因此选择放开所有 IP。如果你部署在特定主机上,那么建议仅仅放开你所需的 IP 地址,这样具安全性。

网络权限

至此我们的设置工作告一段落。

数据导入

工具下载与操作

导入数据需要使用一个数据库连接工具。

访问 MongoDB 官方的 Database Tools 下载页面: https://www.mongodb.com/try/download/database-tools,下载并安装此工具,并将对应的二进制文件所在路径加入 Path

Database Tools

转到 Clusters,点击 Connect 按钮,选择第一个 Driver,会进入如下图所示的界面,选择 Nodejs,得到一个 srv 链接。

SRV 链接

打开个命令行窗口,执行下面的命令,注意将链接替换为刚刚得到的 srv 链接,路径替换为从 leancloud 下载的 gz 的存放路径(前文提到的 111 文件夹)。数据库用户名和密码采用刚才设置的 waline_user 和对应的密码进行替换:

1
mongorestore --uri "mongodb+srv://<db_user>:<db_password>@cluster_name.xxx233.mongodb.net/?appName=cluster_name" --db waline --dir "C:\Users\path\to\gz_folder" --gzip --drop

执行完成是这样的:

执行完成的命令行

验证

我们回到网页验证一下数据是否导入了。前往 Data Explorer,点击 Cluster 旁边的 connect 按钮。

Data Explorer 连接

连接完成后我们展开 waline 这个数据库,看到具有如下的 Collections ,以及右边有对应的数据,即为成功。

数据查看与验证

注意,LeanCloud 数据在导出时默认在文件名后面有一长串 hash,这个是不能被 Waline 识别的,因此需要重命名一下,把 hash 删掉。我这张图上的是已经重命名过的了。

重命名 Collections

获取旧版访问链接

接下来我们获取一下数据库的访问链接,以便对 Waline 进行配置。

转到前几步中获取 srv 链接时的 Cluster 页面,点击 Connect ,这次我们把 SRV Connectuion String 关闭,得到如下图所示的传统链接:

获取旧版链接

根据链接,我们可以整理出配置所需要的环境变量。注意,下面的是一个示例,需要按照你的情况进行修改:

1
2
3
4
5
6
7
8
MONGO_HOST=["ac-bxxxxx7-shard-00-00.zxxxxx.mongodb.net","ac-bxxxx7-shard-00-01.xxxxxp.mongodb.net","ac-xxxxx7-shard-00-02.zyxxxxxp.mongodb.net"]
MONGO_PORT=[27017,27017,27017,27017]
MONGO_DB=waline
MONGO_USER=waline_user
MONGO_PASSWORD=waline_user_passwd
MONGO_REPLICASET=atlas-xxxxxx-shard-0
MONGO_AUTHSOURCE=admin
MONGO_OPT_SSL=true

重新部署

本人的 Waline 托管在 Github 上,使用 Vercel 部署。

登录 Vercel 控制台,打开对应项目的设置页面,将前文中获得的数据编辑好,填入 Vercel 的环境变量。

下图是设置好的新变量,一共有 8 个。同时,把旧变量加上 BAK 后缀,使其失效。

环境变量编辑

添加完环境变量以后,记得 Redeploy,再过几分钟,新的评论系统即可上线,完成迁移。

重新部署

我们可以尝试进入 Waline 的后台检查一下,所有的评论的确都迁移过来了。

Waline 后台

相关文章

在配置和撰写本文过程中,参考了以下文章,在此表示感谢:

  1. 将 Waline 从 LeanCloud 迁移到 MongoDB

注释


  1. https://github.com/orgs/walinejs/discussions/3370↩︎

  2. https://waline.js.org/guide/database.html↩︎