MongoDB
 sql >> Teknologi Basis Data >  >> NoSQL >> MongoDB

Bagaimana cara mengonversi JSON bersarang sewenang-wenang ke CSV dengan jq – sehingga Anda dapat mengonversinya kembali?

Berikut tocsv dan fromcsv fungsi memberikan solusi untuk masalah yang disebutkan kecuali satu komplikasi mengenai persyaratan (6) tentang header. Pada dasarnya, persyaratan ini dapat dipenuhi menggunakan fungsi yang diberikan di sini dengan menambahkan langkah transposisi matriks.

Apakah langkah transposisi ditambahkan atau tidak, keuntungan dari pendekatan yang diambil di sini adalah tidak ada batasan pada kunci atau nilai JSON. Secara khusus, mereka mungkin berisi titik (titik), baris baru dan/atau karakter NUL.

Dalam contoh, array objek diberikan, tetapi sebenarnya aliran dokumen JSON yang valid dapat digunakan sebagai input ke tocsv; berkat keajaiban jq, aliran asli akan dibuat ulang oleh fromcsv (dalam arti kesetaraan entitas demi entitas).

Tentu saja, karena tidak ada standar CSV, CSV yang dihasilkan oleh tocsv fungsi mungkin tidak dipahami oleh semua prosesor CSV. Khususnya, harap perhatikan bahwa tocsv fungsi yang didefinisikan di sini memetakan baris baru dalam string JSON atau nama kunci ke string dua karakter "\n" (yaitu, garis miring terbalik literal diikuti oleh huruf "n"); operasi kebalikan melakukan terjemahan terbalik untuk memenuhi "pulang pergi" persyaratan.

(Penggunaan tail hanya untuk menyederhanakan presentasi; akan sulit untuk memodifikasi solusi untuk menjadikannya satu-satunya-jq.)

CSV dihasilkan dengan asumsi bahwa nilai apa pun dapat dimasukkan dalam bidang selama (a) bidang dikutip, dan (b) tanda kutip ganda di dalam bidang digandakan.

Solusi umum apa pun yang mendukung "pulang pergi" pasti akan menjadi agak rumit. Alasan utama mengapa solusi yang disajikan di sini lebih kompleks daripada yang diperkirakan adalah karena kolom ketiga ditambahkan, sebagian untuk memudahkan membedakan antara bilangan bulat dan string bernilai bilangan bulat, tetapi terutama karena memudahkan untuk membedakan antara ukuran-1 dan ukuran -2 array yang dihasilkan oleh jq's--stream pilihan. Tak perlu dikatakan, ada cara lain untuk mengatasi masalah ini; jumlah panggilan ke jq juga bisa dikurangi.

Solusinya disajikan sebagai skrip pengujian yang memeriksa persyaratan bolak-balik pada kasus uji yang jitu:

#!/bin/bash

function json {
    cat<<EOF
[
  {
    "a": 1,
    "b": [
      1,
      2,
      "1"
    ],
    "c": "d\",ef",
    "embed\"ed": "quote",
    "null": null,
    "string": "null",
    "control characters": "a\u0000c",
    "newline": "a\nb"
  },
  {
    "x": 1
  }
]
EOF
}

function tocsv {
 jq -ncr --stream '
   (["path", "value", "stringp"],
    (inputs | . + [.[1]|type=="string"]))
   | map( tostring|gsub("\"";"\"\"") | gsub("\n"; "\\n"))
   | "\"\(.[0])\",\"\(.[1])\",\(.[2])" 
'
}

function fromcsv { 
    tail -n +2 | # first duplicate backslashes and deduplicate double-quotes
    jq -rR '"[\(gsub("\\\\";"\\\\") | gsub("\"\"";"\\\"") ) ]"' |
    jq -c '.[2] as $s 
           | .[0] |= fromjson 
           | .[1] |= if $s then . else fromjson end 
           | if $s == null then [.[0]] else .[:-1] end
             # handle newlines
           | map(if type == "string" then gsub("\\\\n";"\n") else . end)' |
    jq -n 'fromstream(inputs)'
}    

# Check the roundtrip:
json | tocsv | fromcsv | jq -s '.[0] == .[1]' - <(json)

Berikut adalah CSV yang akan dihasilkan oleh json | tocsv , kecuali bahwa SO tampaknya melarang NUL literal, jadi saya telah menggantinya dengan \0 :

"path","value",stringp
"[0,""a""]","1",false
"[0,""b"",0]","1",false
"[0,""b"",1]","2",false
"[0,""b"",2]","1",true
"[0,""b"",2]","false",null
"[0,""c""]","d"",ef",true
"[0,""embed\""ed""]","quote",true
"[0,""null""]","null",false
"[0,""string""]","null",true
"[0,""control characters""]","a\0c",true
"[0,""newline""]","a\nb",true
"[0,""newline""]","false",null
"[1,""x""]","1",false
"[1,""x""]","false",null
"[1]","false",null


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Halaman Meteor Menyegarkan dengan Klik Tombol

  2. Batas waktu driver MongoDB C#

  3. Driver MongoDB-Java:Tangkap pengecualian saat penyisipan gagal

  4. Bagaimana cara mongoexport atribut dari array objek ke CSV?

  5. dokumen luwak. simpan tidak berfungsi