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

使用PowerShell转换含嵌套数组的JSON到CSV耗时过长问题排查

PowerShell处理嵌套JSON转CSV:解决性能慢与数据集中在单个单元格的问题

首先得说你当前代码的几个问题,这也是导致慢和格式异常的核心原因:

  • 空数组展开的坑:你的代码里用了Select * -Expand tagsOfEntities,但tagsOfEntities是空数组,这会让PowerShell把每个problem对象拆分成空条目,不仅打乱数据结构,还会增加大量不必要的处理量,直接拖慢运行速度。
  • 连续Expand的逻辑错误:链式调用多次Select -Expand会让数据扁平化的逻辑彻底混乱,尤其是当有多个嵌套结构时,这种方式无法正确把外层属性和嵌套数组的每个条目关联起来,最后输出的CSV自然会因为结构不对,所有数据挤在一个单元格里。
  • 性能浪费:这种链式操作会反复遍历和转换对象,当JSON数据量较大时,性能损耗会被无限放大,导致运行时长长达2小时。

接下来给你一个更高效且能正确输出CSV的解决方案,核心思路是手动控制嵌套结构的扁平化,明确把外层属性和每个嵌套条目合并:

# 读取并解析JSON文件
$jsonContent = Get-Content C:\Documents\feed.json -Raw | ConvertFrom-Json

# 逐层处理嵌套结构,生成扁平化的对象集合
$flattenedRecords = $jsonContent.result.problems | ForEach-Object {
    $currentProblem = $_
    # 遍历ranked数组,将每个ranked项与外层problem属性合并
    foreach ($rankedItem in $currentProblem.ranked) {
        [PSCustomObject]@{
            # 外层problem的基础属性
            id                  = $currentProblem.id
            displayName         = $currentProblem.displayName
            impact              = $currentProblem.impact
            status              = $currentProblem.status
            tagsOfEntities      = $currentProblem.tagsOfEntities -join ';' # 空数组转为空字符串,有内容则用分号分隔
            RootCause           = $currentProblem.RootCause
            
            # ranked数组的属性
            entityId            = $rankedItem.entityId
            entityName          = $rankedItem.entityName
            severityLevel       = $rankedItem.severityLevel
            
            # 嵌套对象affectedCounts的属性,重命名避免歧义
            affected_INFRA      = $currentProblem.affectedCounts.INFRA
            affected_STRUCTURE  = $currentProblem.affectedCounts.STRUCTURE
            affected_APPLICATION= $currentProblem.affectedCounts.APPLICATION
            
            # 嵌套对象recoveredCounts的属性
            recovered_INFRA     = $currentProblem.recoveredCounts.INFRA
            recovered_STRUCTURE = $currentProblem.recoveredCounts.STRUCTURE
            recovered_APPLICATION = $currentProblem.recoveredCounts.APPLICATION
        }
    }
}

# 转换为CSV并输出,指定UTF8编码避免乱码
$flattenedRecords | ConvertTo-Csv -NoTypeInformation | Out-File C:\Documents\output.csv -Encoding UTF8

这个方案的优势:

  1. 性能更优:只遍历必要的层级,没有多余的Expand操作,大幅减少不必要的对象转换和遍历,运行速度会快很多。
  2. 格式正确:每个ranked条目都会和对应的problem属性组合成一行,CSV的每列对应一个属性,不会出现数据集中在单个单元格的情况。
  3. 灵活可控:你可以根据需求调整嵌套属性的处理方式,比如tagsOfEntities如果有内容,用分号分隔成字符串,方便在CSV中查看;如果不需要某个属性,直接从PSCustomObject里删掉就行。

另外补充两个小建议:

  • 如果你的JSON文件非常大,可以考虑用Get-Content -ReadCount 1000分批读取解析,但对于大多数场景,上面的代码已经足够高效。
  • 一定要加-Encoding UTF8参数,避免Out-File默认编码导致的乱码问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 06:57:24