Наиболее эффективный способ преобразования BigQuery JSON из API в CSV - PullRequest
0 голосов
/ 05 ноября 2019

Доброе утро / день всем,

Когда вы запускаете запрос к Google BigQuery API, вы получаете ответ в JSON-файле, который странным образом структурирован.

Вы можете найти столбецимена в $ColumnName = $Response.schema.fields.name, но значения для столбцов в $Row = $Response.rows.

Вот как выглядят строки:

{
        "f":  [
                  "@{v=@2019-11-04 14:14:49}",
                  "@{v=@8349531079148439128}",
                  "@{v=Returning Visitor}",
                  "@{v=1}",
                  "@{v=Yes}",
                  "@{v=Good news!}",
                  "@{v=1}",
                  "@{v=0}",
                  "@{v=1}",
                  "@{v=google}",
                  "@{v=organic}",
                  "@{v=(not set)}",
                  "@{v=(not provided)}",
                  "@{v=mobile}",
                  "@{v=/}",
                  "@{v=/}",
                  "@{v=No}",
                  "@{v=Yes}",
                  "@{v=No}"
              ]
    },
    {
        "f":  [
                  "@{v=@2019-11-04 08:52:48}",
                  "@{v=@3602395308467676896}",
                  "@{v=New Visitor}",
                  "@{v=4a9bcd67a01d}",
                  "@{v=Yes}",
                  "@{v=We\u0027re happy to carry out the work.}",
                  "@{v=}",
                  "@{v=1}",
                  "@{v=0}",
                  "@{v=ivr}",
                  "@{v=sms}",
                  "@{v=ivr-deflect}",
                  "@{v=(not set)}",
                  "@{v=mobile}",
                  "@{v=/}",
                  "@{v=/}",
                  "@{v=Yes}",
                  "@{v=No}",
                  "@{v=No}"
              ]
    }

Таким образом, каждая строка присваивается "f" и значениямкаждому столбцу присваивается «v», внутри «f».

Поэтому, чтобы получить их в правильном формате, я написал пару циклов ниже:

$Data = @()
for($j=0; $j -lt $RowCount; $j++){
    $Datarow = New-Object PSObject
    For($i=0; $i -lt $ColumnCount; $i++){
        $Datarow | Add-Member -type NoteProperty -Name $ColumnName[$i] -Value $Row[$j].f.v[$i]
    }
    $Data += $Datarow
}

Но, как вы можетепредставьте, это цитата медленная. Особенно на нашей немного устаревшей серверной машине, где это будет запланировано.

Знаете ли вы о лучших способах сделать это?

С уважением, Jarek

1 Ответ

1 голос
/ 05 ноября 2019

Есть два способа ускорить ваш код:

  • Избегайте постепенного "расширения" вашего массива с помощью +=, потому что для этого требуется создать новый массивза кулисами в каждой итерации;вместо этого используйте цикл for в качестве выражения и позвольте PowerShell собрать его вывод в массив для вас.

  • Избегайте дорогостоящихNew-Object и Add-Member вызывает сначала создание пар свойство-значение в упорядоченной хеш-таблице (что намного быстрее), а затем приведение этого хэш-значения к [pscustomobject] для преобразования его в пользовательский объект(PSv3 +).

$Data = 
  for ($j=0; $j -lt $RowCount; $j++){
      $Datarow = [ordered] @{} # an ordered hashtable that represents a row.
      For($i=0; $i -lt $ColumnCount; $i++){
        $Datarow[$ColumnName[$i]] = $Row[$j].f.v[$i]
      }
      [pscustomobject] $Datarow # convert to a custom object and output.
  }

Обновление : Jarek (OP) сообщает, что это решение примерно в 3 раза быстрее, чем оригинальное.
Без[pscustomobject] приведение - т. е. с помощью непосредственного использования экземпляров хеш-таблиц - коэффициент около 5, но обратите внимание, что в настоящее время (начиная с PowerShell Core 7.0.0-preview.5) нельзя использовать хеш-таблицы с Export-Csv / ConvertTo-Csv,Добавление поддержки для этого является предметом этого запроса функции на GitHub .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...