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

如何在Ruby中从文件行提取数据?处理千万行数据遇问题

解决1000万行MongoDB导出数据的id提取问题

看起来你遇到的是MongoDB导出的非标准JSON格式问题——因为ObjectId不是合法的JSON类型,所以直接用JSON.parse会报错。针对1000万行的大数据量,我给你两个实用的解决方案,兼顾性能和稳健性:

方案一:精准正则匹配(性能最优)

因为你的每行格式非常固定,"id"后面跟着的是整数,我们可以用专门匹配数字的正则直接提取,完全避免JSON解析的开销:

# 提前编译正则并冻结,提升循环内的匹配速度
ID_PATTERN = /"id" : (\d+)/.freeze

# 用File.foreach逐行读取,避免一次性加载大文件到内存
File.foreach('your_large_file.txt').with_index do |line, idx|
  # 跳过空行,减少无效处理
  next if line.strip.empty?

  if match_result = ID_PATTERN.match(line)
    listing_id = match_result[1].to_i
    # 这里写你的id处理逻辑
  else
    # 记录异常行,方便后续排查
    puts "Warning: Invalid line format at index #{idx}: #{line.strip}"
  end
end

这个方法的核心是用(\d+)精准匹配"id" :后面的所有数字,不会把末尾的 }包含进来,而且逐行读取的方式内存占用极低,适合处理千万级别的大文件。

方案二:修复JSON格式后解析(稳健性更强)

如果你之后可能需要提取其他字段,或者担心格式有微小变动,我们可以先把非标准的ObjectId替换成合法JSON字符串,再用JSON.parse解析:

require 'json'

# 替换ObjectId为JSON合法字符串的正则
FIX_JSON_PATTERN = /ObjectId\("([^"]+)"\)/.freeze

File.foreach('your_large_file.txt').with_index do |line, idx|
  next if line.strip.empty?

  begin
    # 把ObjectId("xxx")替换成"xxx",让整行变成合法JSON
    fixed_line = line.gsub(FIX_JSON_PATTERN, '"\1"')
    data = JSON.parse(fixed_line)
    listing_id = data.fetch("id")
    # 处理逻辑
  rescue JSON::ParserError => e
    puts "Error parsing line #{idx}: #{e.message} | Line content: #{line.strip}"
  end
end

这个方法的优势是能完整解析整行数据,后续要提取其他字段(比如_id的字符串值)也很方便,唯一的小缺点是比纯正则多了字符串替换和JSON解析的步骤,性能稍逊,但对于千万级别数据来说依然足够高效。

额外优化建议

  1. 尽量避免用File.readlines一次性读取整个文件,会占用大量内存;File.foreach是逐行读取,内存友好。
  2. 正则表达式提前编译并冻结(.freeze),可以避免循环内重复编译正则的开销。
  3. 加上空行判断和异常捕获,能让程序在遇到格式异常的行时不会崩溃,还能记录问题方便排查。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:12:38