我正在尝试确定一个程序/软件,该程序/软件将使我能够有效地提取大量大型CSV文件(总计40+ GB),并输出具有导入到Elasticsearch(ES)所需的特定格式的JSON文件。
jq可以有效地获取如下数据:
file1: id,age,gender,wave 1,49,M,1 2,72,F,0 file2: id,time,event1 1,4/20/2095,V39 1,4/21/2095,T21 2,5/17/2094,V39
按ID进行汇总(这样,多个文件中CSV行中的所有JSON文档都属于一个id条目),输出如下所示:
{"index":{"_index":"forum_mat","_type":"subject","_id":"1"}} {"id":"1","file1":[{"filen":"file1","id":"1","age":"49","gender":"M","wave":"1"}],"file2":[{"filen":"file2","id":"1","time":"4/20/2095","event1":"V39"},{"filen":"file2","id":"1","time":"4/21/2095","event1":"T21"}]} {"index":{"_index":"forum_mat","_type":"subject","_id":"2"}} {"id":"2","file1":[{"filen":"file1","id":"2","age":"72","gender":"F","wave":"0"}],"file2":[{"filen":"file2","id":"2","time":"5/17/2094","event1":"V39"}]}
我用Matlab编写了一个脚本,但由于担心它的执行速度慢得多。我可能需要花费数月的时间来处理所有40 GB以上的数据。有人告诉我Logstash(ES首选的数据输入工具)在这种类型的聚合上并不擅长。
正如其中一项注释中所建议的那样,我最终使用SQL以我所需的格式导出JSON。另一个线程大有帮助。最后,我选择将给定的SQL表输出到其自己的JSON文件中,而不是将它们组合在一起(文件大小变得难以管理)。这样做的代码结构是这样的,您可以为Bulk API和JSON数据行生成命令行:
create or replace function format_data_line(command text, data_str text) returns setof text language plpgsql as $$ begin return next command; return next replace( regexp_replace(data_str, '(\d\d\d\d-\d\d-\d\d)T', '\1 ', 'g'), e' \n ', ''); end $$; COPY ( with f_1 as( SELECT id, json_agg(fileX.*) AS tag FROM forum.file3 GROUP BY id ) SELECT format_data_line( format('{"update":{"_index":"forum2","_type":"subject","_id":%s}}',a.id), format('{"doc":{"id":%s,"fileX":%s}}', a.id, a.tag)) FROM f_1 a ) TO '/path/to/json/fileX.json';
使用Bulk API导入较大的文件也存在问题(内存不足Java错误),因此在特定时间只需要脚本就可以将数据的子集发送到Curl(在Elasticsearch中建立索引)。该脚本的基本结构为:
#!/bin/bash FILE=$1 INC=100 numline=`wc -l $FILE | awk '{print $1}'` rm -f output/$FILE.txt for i in `seq 1 $INC $numline`; do TIME=`date +%H:%M:%S` echo "[$TIME] Processing lines from $i to $((i + INC -1))" rm -f intermediates/interm_file_$i.json sed -n $i,$((i +INC - 1))p $FILE >> intermediates/interm_file_$i.json curl -s -XPOST localhost:9200/_bulk --data-binary @intermediates/interm_file_$i.json >> output/$FILE.txt done
应在脚本文件目录下创建一个“中间”目录。该脚本可以另存为“ ESscript”,并在命令行上运行:
./ESscript fileX.json