You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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)。

测试步骤

  1. 进入MongoDB容器:docker exec -it <容器名> bash
  2. 直接执行带--verbose的mongoimport命令,观察详细日志定位问题。
  3. 若直接命令执行成功,再调试init-mongo.js脚本;若失败,优先排查文件挂载、权限或版本问题。

内容的提问来源于stack exchange,提问作者Stanislav Nasonov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 03:07:03