Docker-Compose容器中mongoimport报JSON输入意外结束错误的解决咨询
解决Docker环境下mongoimport导入JSON时的Unexpected end of JSON input错误
问题背景
在Docker Compose环境中,尝试导入一个2.8MB的有效JSON数组文件到MongoDB,无论直接执行终端命令还是通过init-mongo.js脚本调用mongoimport,均触发错误:mongoimport: Uncaught: SyntaxError: Unexpected end of JSON input。
解决方案
1. 检查文件挂载与权限
- 确认挂载配置:在
docker-compose.yml中确保本地文件已正确挂载到容器指定路径,示例配置:services: mongodb: image: mongo:6.0 volumes: # 替换为本地tickets.json的实际路径 - ./local-path/tickets.json:/.docker/tickets.json:ro - ./init-mongo.js:/docker-entrypoint-initdb.d/init-mongo.js:ro - 验证容器内文件完整性:进入MongoDB容器,执行
cat /.docker/tickets.json或cat /.docker/tickets.json | jq .(需容器内安装jq),确认文件末尾无截断、内容完整。 - 检查文件权限:执行
ls -l /.docker/tickets.json,确保文件拥有可读权限(权限位包含r),若权限不足,可调整本地文件权限或在挂载时添加:z标签解决SELinux问题(如./local-path/tickets.json:/.docker/tickets.json:ro,z)。
2. 修复init-mongo.js脚本问题
当前脚本通过管道传递文件流易引发传输异常,建议直接传递文件路径参数,同时完善错误处理:
const fs = require('fs'); const { spawn } = require('child_process'); const importTickets = async () => { try { const path = '/.docker/tickets.json'; if (!fs.existsSync(path)) { throw new Error(`Файл ${path} не найден.`); } // 直接传递--file参数,替代管道传输 const mongoimport = spawn('mongoimport', [ '--db=pdd', '--collection=tickets', '--type=json', '--jsonArray', '--file', path, '--verbose' // 添加详细日志便于排查 ]); const stdoutChunks = []; const stderrChunks = []; mongoimport.stdout.on('data', (data) => stdoutChunks.push(data)); mongoimport.stderr.on('data', (data) => stderrChunks.push(data)); await new Promise((resolve, reject) => { mongoimport.on('close', (code) => { const stdoutStr = Buffer.concat(stdoutChunks).toString(); const stderrStr = Buffer.concat(stderrChunks).toString(); if (code === 0) { // 从输出中提取导入数量,避免JSON.parse失败 const nInsertedMatch = stdoutStr.match(/nInserted:\s*(\d+)/); const nInserted = nInsertedMatch ? parseInt(nInsertedMatch[1], 10) : 0; console.log(`${nInserted} документов было импортировано в коллекцию tickets.`); resolve(); } else { console.error(`Произошла ошибка при импорте данных в коллекцию tickets. ${stderrStr}`); reject(new Error(stderrStr)); } }); // 监听子进程错误 mongoimport.on('error', (err) => { console.error('Ошибка запуска mongoimport:', err.message); reject(err); }); }); } catch (err) { console.error(err.message); } }; importTickets();
3. 确保MongoDB与mongoimport版本兼容
- 在
docker-compose.yml中指定具体的MongoDB版本(如mongo:6.0),避免latest标签导致版本不稳定。 - 进入容器执行
mongoimport --version,确认其版本与MongoDB版本一致,避免跨版本兼容性问题。
4. 调整mongoimport参数优化导入
- 添加
--batchSize参数分批次导入,降低单批次数据量:mongoimport --db=pdd --collection=tickets --type=json --file /.docker/tickets.json --jsonArray --batchSize 1000 --verbose - 若网络或容器资源有限,可添加
--numInsertionWorkers参数设置并发导入线程数(如--numInsertionWorkers 2)。
测试步骤
- 进入MongoDB容器:
docker exec -it <容器名> bash - 直接执行带
--verbose的mongoimport命令,观察详细日志定位问题。 - 若直接命令执行成功,再调试
init-mongo.js脚本;若失败,优先排查文件挂载、权限或版本问题。
内容的提问来源于stack exchange,提问作者Stanislav Nasonov
相关产品推荐
相关产品推荐

