845 字
4 分钟
Hugo博客文章过长导致search文件无法上传到algolia的问题
问题
我hugo使用algolia进行搜索,在构建hugo生成静态文件后,将search.json传到algolia中,就可以进行搜索。现在出现了一个小问题,就是我有一篇文章比较长,导致在上传时超过algolia免费套餐的限制,报错如下
/opt/1panel/www/sites/cbba-top/index/blog-FixIt/node_modules/atomic-algolia/lib/update.js:69 if (err) throw err; ^AlgoliaSearchError: Record at the position 1 objectID=/posts/555833d/:0:0 is too big size=10236/10000 bytes. Please have a look at https://www.algolia.com/doc/guides/sending-and-managing-data/prepare-your-data/in-depth/index-and-records-size-and-usage-limitations/#record-size-limits at success (/opt/1panel/www/sites/cbba-top/index/blog-FixIt/node_modules/algoliasearch/src/AlgoliaSearchCore.js:377:32) at process._tickCallback (internal/process/next_tick.js:68:7)npm ERR! code ELIFECYCLEnpm ERR! errno 1npm ERR! blog-fixit@1.0.0 algolia: `atomic-algolia`npm ERR! Exit status 1npm ERR!npm ERR! Failed at the blog-fixit@1.0.0 algolia script.npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:npm ERR! /root/.npm/_logs/2025-07-27T14_49_03_656Z-debug.log
解决思路有两个:
- 生成静态文件后,编写一个脚本将search.json中超出10k的文章拆分成多个algolia记录
- 生成静态文件后,编写一个脚本将
于是我测试了一下hugo使用algolia在网页中搜索好不好用,测试下来发现还行,但是涉及到某个细微的点就容易搜索不到,比如我哪个文章中提及了点别的技术,我想不起来是哪篇文章就只能靠搜索,这时网页大概率是搜不出来的,还是要靠本地搜索,所以我选择在生成search.json后将文章过长的部分截断
通过truncate.js截断search.json
以下是针对Algolia
记录大小限制的截断代码truncate.js
,实现按字节数检测超长内容并截断
在hugo
主目录创建truncate.js
文件,内容如下:
const fs = require('fs');const path = require('path');
const INPUT_FILE = 'search.json';const OUTPUT_FILE = 'search-truncated.json';const MAX_BYTES = 9000; // 10KB,留出余量
// UTF-8 字节计算函数function getByteLength(str) { return Buffer.byteLength(str, 'utf8');}
// 截断内容,使其不超过 MAX_BYTES 字节function truncateToBytes(str, maxBytes) { let bytes = 0; let result = ''; // 通过for循环,逐个读取字符,每次都判断读取到现在位置的总字节数是否超过最大值, // 如果没超过则将该字符添加到result字符串中,直至总字节数超过最大值,此时的result字符串就是截断后保留的部分 // 逐个字符处理可以避免在字符中间截断导致乱码 for (let i = 0; i < str.length; i++) { const char = str[i]; const charByteLength = Buffer.byteLength(char, 'utf8'); if (bytes + charByteLength > maxBytes) { break; } bytes += charByteLength; result += char; }
return result;}
try { const rawData = fs.readFileSync(INPUT_FILE, 'utf8'); const records = JSON.parse(rawData); // 解析json数据
console.log(`✅ 成功加载 ${records.length} 条记录`);
const processed = records.map((item, index) => { const contentBytes = getByteLength(item.content || ''); // 计算内容字节数 const title = item.title || `第${index + 1}条记录(无标题)`; // 处理空标题
// 如果字节数超过限制则截断 if (contentBytes > MAX_BYTES) { const truncated = truncateToBytes(item.content, MAX_BYTES); console.log(`✂️ 截断处理,标题: ${title},原字节数: ${contentBytes} -> 截断后: ${getByteLength(truncated)} 字节`); return { ...item, content: truncated }; // 返回截断后的新对象 } else { console.log(`👍 无需截断,标题: ${title},字节数: ${contentBytes}`); return item; // 返回原对象 } });
fs.writeFileSync(OUTPUT_FILE, JSON.stringify(processed, null, 2), 'utf8'); console.log(`✅ 写入成功: ${OUTPUT_FILE}`);} catch (err) { console.error(`❌ 错误: ${err.message}`);}
修改deploy.sh
文件
- 将上传的文件由
public/search.json
改为主目录中新生成的search-truncated.json
文件 - 添加执行截断脚本的指令
#!/bin/bash
# 构建 Hugo 网站hugo
# 对超过algolia要求的大小的记录进行截断node truncate.js
# 上传到 AlgoliaALGOLIA_APP_ID=ZSH625MG3A \ALGOLIA_ADMIN_KEY=a4221316a50d7dea962f44d3593eae86 \ALGOLIA_INDEX_NAME=index.zh-cn \ALGOLIA_INDEX_FILE=search-truncated.json \npm run algolia
Hugo博客文章过长导致search文件无法上传到algolia的问题
https://fuwari.cbba.top/posts/hugo博客文章过长导致search文件无法上传到algolia的问题/