基于MongoDB Atlas的博客热榜

这两天小米在送 Token,老苏也去凑了下热闹

不过没有什么拿的出手的成果,所以跟别人晒出来的相比差了很多

接入 Claude Code CLI 后,做了两件事情:

  1. Web Clipper 插件最近设置 为知笔记 一直有报错,而老苏的会员还有将近 2 年;

  2. 一月份的时候,老苏完成了 将Waline从LeanCloud迁移到MongoDB,当时留了个尾巴,就是 热榜 还是使用的 LeanCloud 国际版的数据;

对应我们非程序员来说,Vibe Coding 最大的意义就在于,只要有源码,我们完全可以自己搞定问题,而不是无休止的等待

对于问题一,只用了 5 轮,不仅解决了报错,还顺便解决了每次剪藏页面都要动态刷新知识库目录,导致等待时间很长的问题。

看起来自主性比较强,只是 Token 消耗的比较快,大约消耗了 15%。如果你也遇到同样的问题,可以试试。代码我放出来了,https://github.com/wbsu2003/web-clipper,但是我建议你自己去下源码 https://github.com/webclipper/web-clipper,再根据自己的需要修改

今天主要讲讲问题二,AI 推荐了不少于 5 个方案,但是老苏选择了一个改动最小,最安全、最轻量的方案,也就是放弃实时更新,采用定时生成 JSON 的方式

  • GitHub Actions 定时查 MongoDB,生成 hot-posts.json
  • 部署到 Hexosource/ 目录,随博客一起发布
  • 定时更新部署分支 (master) ,无需重新构建 Hexo

部署步骤

第一步:设置 GitHub Secrets

进入源码仓库 → SettingsSecrets and variablesActionsNew repository secret

Secret
MONGODB_URI mongodb://<db_user>:<db_password>@cluster0-shard-xxx.mongodb.net:27017,.../?ssl=true&replicaSet=atlas-xxx-shard-0&authSource=admin&retryWrites=true&w=majority
MONGODB_DB waline

注意:优先用 Waline 支持的标准连接串。所以使用了 mongodb:// 格式,而非 mongodb+srv:// 格式。

第二步:添加 query.mjs

query.mjs 文件放到源码仓库根目录:

javascript 复制代码
// query.mjs
import { MongoClient } from "mongodb";
import { writeFileSync } from "fs";

const uri = process.env.MONGODB_URI;
const dbName = process.env.MONGODB_DB || "waline";

if (!uri) {
  console.error("MONGODB_URI is not set");
  process.exit(1);
}

const client = new MongoClient(uri);

try {
  await client.connect();
  const col = client.db(dbName).collection("Counter");

  const rows = await col
    .find({ id: { $ne: 0 } })
    .sort({ time: -1 })
    .limit(100)
    .toArray();

  const result = [];
  for (const doc of rows) {
    if (result.length >= 30) break;

    const url = doc.url || "";
    let title = "";
    try {
      title = decodeURIComponent(url).split("/")[4] || "";
    } catch {}

    const heat = doc.time || 0;
    const segment = decodeURIComponent(url).split("/")[1] || "";

    if (doc.xid !== undefined) continue;
    if (!title || title.trim().length === 0) continue;
    if (["page", "categories", "message", "about"].includes(segment)) continue;
    if (heat < 700) continue;

    result.push({ rank: result.length + 1, title, url, heat });
  }

  const outPath = process.env.OUTPUT_PATH || "source/hot-posts.json";
  writeFileSync(outPath, JSON.stringify(result, null, 2));
  console.log(`Wrote ${result.length} entries to ${outPath}`);
} catch (err) {
  console.error("Query failed:", err.message);
  process.exit(1);
} finally {
  await client.close();
}

第三步:添加定时工作流

将文件放到 .github/workflows/update-hot-posts.yml

yaml 复制代码
name: Update Hot Posts

on:
  schedule:
    - cron: "17 * * * *"   # 每小时第17分钟
  workflow_dispatch:         # 支持手动触发

jobs:
  update:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout source repo
        uses: actions/checkout@v4
        with:
          repository: wbsu2003/myblog  # 源码仓库

      - name: Checkout deploy repo
        uses: actions/checkout@v4
        with:
          repository: wbsu2003/wbsu2003.github.io  # 博客仓库
          ref: master
          path: .deploy_git
          token: ${{ secrets.DEPLOY_TOKEN }}

      - name: Use Node.js 22
        uses: actions/setup-node@v4
        with:
          node-version: "22"

      - name: Query and update
        env:
          MONGODB_URI: ${{ secrets.MONGODB_URI }}
          MONGODB_DB: ${{ secrets.MONGODB_DB }}
          OUTPUT_PATH: .deploy_git/hot-posts.json
        run: |
          npm install mongodb
          node query.mjs

      - name: Commit if changed
        working-directory: .deploy_git
        run: |
          git config user.name "github-actions[bot]"
          git config user.email "github-actions[bot]@users.noreply.github.com"
          git remote set-url origin https://x-access-token:${{ secrets.DEPLOY_TOKEN }}@github.com/wbsu2003/wbsu2003.github.io.git
          git add hot-posts.json
          git diff --cached --quiet || git commit -m "chore: update hot posts" && git push

第四步:修改现有的 deploy.yml

deploy.ymlInstall dependenciesDeploy hexo 之间,新增一步:

yaml 复制代码
      - name: Generate hot posts
        env:
          MONGODB_URI: ${{ secrets.MONGODB_URI }}
          MONGODB_DB: ${{ secrets.MONGODB_DB }}
          # 不设置 OUTPUT_PATH,默认写到 source/hot-posts.json,随 Hexo 构建一起处理
        run: |
          npm install mongodb
          node query.mjs

这样每次 pushmain 构建博客时,也会顺便生成一次热榜。

第五步:前端引入 hot-posts.js

Hexo 热榜页面中引入以下脚本,页面中需要有 <div id="top"></div>

javascript 复制代码
// hot-posts.js
(function () {
  var container = document.getElementById("top");
  if (!container) return;

  container.innerHTML = "<p>加载中...</p>";

  fetch("/hot-posts.json")
    .then(function (res) {
      if (!res.ok) throw new Error("HTTP " + res.status);
      return res.json();
    })
    .then(function (data) {
      if (!data.length) {
        container.innerHTML = "<p>暂无热榜数据</p>";
        return;
      }
      container.innerHTML = "";
      data.forEach(function (item) {
        var p = document.createElement("p");
        p.innerHTML =
          "<span>" + item.rank + "、</span>" +
          "<font color='#ff4d4f'>【文章热度:" + item.heat + "℃】</font>" +
          "<a href='" + item.url + "'>" + item.title + "</a>";
        container.appendChild(p);
      });
    })
    .catch(function (err) {
      console.error("热榜加载失败:", err);
      container.innerHTML = "<p>热榜加载失败,请刷新重试</p>";
    });
})();

验证

  1. 进入源码仓库 → ActionsUpdate Hot PostsRun workflow → 手动触发一次
  1. 检查部署博客仓库的分支(master)是否生成了 hot-posts.json
  2. 访问 https://laosu.tech/hot-posts.json 确认能正常返回 JSON
  1. 访问热榜页面确认渲染正常

说明

如何共用

query.mjs 通过 OUTPUT_PATH 环境变量控制 JSON 写入位置:

javascript 复制代码
const outPath = process.env.OUTPUT_PATH || "source/hot-posts.json";
工作流 是否设置 OUTPUT_PATH 写入位置 原因
update-hot-posts.yml 设置为 .deploy_git/hot-posts.json 直接写到部署仓库的 master 分支 → /hot-posts.json 跳过 Hexo 构建,只更新这一个文件
deploy.yml 不设置(用默认值) 先写到 source/hot-posts.json,Hexo 构建时复制到 public/,部署时推到根目录 → /hot-posts.json 随 Hexo 构建流程一起处理

两个工作流最终效果一样:部署分支根目录的 /hot-posts.json。区别是定时工作流不需要跑整个 Hexo 构建。这样两个工作流用同一份脚本,不需要维护两份代码。

文件清单

所有文件都放在源码仓库中:

文件 位置 作用
query.mjs 仓库根目录 查询 MongoDB,生成 JSON
update-hot-posts.yml .github/workflows/ 每小时定时更新热榜,结果推到部署仓库
index.md 热榜页面,例如 index.md 前端渲染热榜

最终文件结构

bash 复制代码
myblog/
├── .github/
│   └── workflows/
│       ├── deploy.yml              ← 博客构建部署(增加了热榜生成)
│       └── update-hot-posts.yml    ← 新增每小时定时更新热榜
├── source/
│   └── top/
│       └── index.md                ← 替换现有的热榜页面
├── query.mjs                       ← 新增 MongoDB 查询脚本
└── ...

参考文档

Xiaomi MiMo 100T

地址:https://100t.xiaomimimo.com/
Xiaomi MiMo 开放平台

地址:https://platform.xiaomimimo.com/console/plan-manage
用GitHub Actions自动部署Hexo | 老苏的blog

地址:https://laosu.tech/2022/01/24/用GitHub Actions自动部署Hexo

相关推荐
Bert.Cai5 小时前
MySQL RAND()函数详解
数据库·mysql
怪我冷i5 小时前
多租户系统PostgreSQL
数据库·postgresql
发现你走远了5 小时前
极简后端环境搭建:一行 Docker 命令部署四大核心数据库(避坑 PG 18+)
数据库·docker·容器
北重楼016 小时前
如何取消一个挂起的 PostgreSQL 查询
数据库·postgresql
与数据交流的路上6 小时前
mysql参数-优化器 range_optimizer_max_mem_size 相关
数据库·mysql
PaperData6 小时前
2012-2022年农业产业结构高级化
数据库·人工智能·数据分析·经管
喝可乐的希饭a6 小时前
MYSQL的mvcc
数据库·mysql
冷小鱼6 小时前
Valkey 深度剖析:Redis 最佳平替的技术全景
数据库·redis·缓存·valkey
Deryck_德瑞克6 小时前
Nacos适配Kingbase数据库
数据库·windows