У меня есть набор данных JSON с примерно 8,7 миллионами пар значений ключей, извлеченных из хранилища Redis, где каждый ключ гарантированно будет 8-значным числом, а ключ представляет собой 8-буквенно-цифровое значение, т.е.
[{
"91201544":"INXX0019",
"90429396":"THXX0020",
"20140367":"ITXX0043",
...
}]
Чтобы уменьшить использование памяти Redis, я хочу преобразовать это в хэш хэшей, где ключ префикса хэша — это первые 6 символов ключа (см. эта ссылка), а затем сохраните ее обратно в Redis.
В частности, я хочу, чтобы моя результирующая структура данных JSON (которую я затем напишу некоторый код для анализа этой структуры JSON и создания командного файла Redis, состоящего из HSET и т. д.) больше походила на
[{
"000000": { "00000023": "INCD1234",
"00000027": "INCF1423",
....
},
....
"904293": { "90429300": "THXX0020",
"90429302": "THXX0024",
"90429305": "THXY0013"}
}]
Поскольку меня впечатлил jq, я пытаюсь стать более опытным в программирование в функциональном стиле, я хотел использовать jq для этой задачи. Пока я придумал следующее:
% jq '.[0] | to_entries | map({key: .key, pfx: .key[0:6], value: .value}) | group_by(.pfx)'
Это дает мне что-то вроде
[
[
{
"key": "00000130",
"pfx": "000001",
"value": "CAXX3231"
},
{
"key": "00000162",
"pfx": "000001",
"value": "CAXX4606"
}
],
[
{
"key": "00000238",
"pfx": "000002",
"value": "CAXX1967"
},
{
"key": "00000256",
"pfx": "000002",
"value": "CAXX0727"
}
],
....
]
Я пробовал следующее:
% jq 'map(map({key: .pfx, value: {key, value}}))
| map(reduce .[] as $item ({}; {key: $item.key, value: [.value[], $item.value]} ))
| map( {key, value: .value | from_entries} )
| from_entries'
который дает мне правильный результат, но также выводит ошибку для каждого уменьшения (я считаю)
jq: error: Cannot iterate over null
Конечный результат
{
"000001": {
"00000130": "CAXX3231",
"00000162": "CAXX4606"
},
"000002": {
"00000238": "CAXX1967",
"00000256": "CAXX0727"
},
...
}
что правильно, но как я могу избежать появления этого предупреждения stderr?