MongoDB
 sql >> Cơ Sở Dữ Liệu >  >> NoSQL >> MongoDB

Làm cách nào để chuyển đổi JSON lồng nhau tùy ý sang CSV với jq - để bạn có thể chuyển đổi lại nó?

tocsv sau và fromcsv các hàm cung cấp giải pháp cho vấn đề đã nêu ngoại trừ một phức tạp liên quan đến yêu cầu (6) liên quan đến tiêu đề. Về cơ bản, yêu cầu này có thể được đáp ứng bằng cách sử dụng các chức năng được đưa ra ở đây bằng cách thêm bước chuyển vị ma trận.

Cho dù có thêm bước chuyển vị hay không, thì ưu điểm của phương pháp được thực hiện ở đây là không có giới hạn nào đối với các khóa hoặc giá trị JSON. Đặc biệt, chúng có thể chứa dấu chấm (dấu chấm), dòng mới và / hoặc ký tự NUL.

Trong ví dụ, một mảng đối tượng được đưa ra, nhưng trên thực tế, bất kỳ luồng tài liệu JSON hợp lệ nào cũng có thể được sử dụng làm đầu vào cho tocsv; nhờ sự kỳ diệu của jq, luồng gốc sẽ được tạo lại bởi fromcsv (theo nghĩa bình đẳng giữa từng thực thể).

Tất nhiên, vì không có tiêu chuẩn CSV nên CSV được tạo bởi tocsv chức năng có thể không được hiểu bởi tất cả các bộ xử lý CSV. Inparticular, xin lưu ý rằng tocsv hàm được xác định ở đây ánh xạ các dòng mới được nhúng trong chuỗi JSON hoặc tên khóa thành chuỗi hai ký tự "\ n" (tức là dấu gạch chéo ngược theo nghĩa đen theo sau là ký tự "n"); phép toán nghịch đảo thực hiện phép dịch ngược để đáp ứng "khứ hồi" yêu cầu.

(Việc sử dụng tail chỉ là để đơn giản hóa việc trình bày; sẽ rất tốt nếu sửa đổi giải pháp để biến nó thành một giải pháp duy nhất.)

CSV được tạo dựa trên giả định rằng bất kỳ giá trị nào cũng có thể được bao gồm trong một trường miễn là (a) trường được trích dẫn và (b) dấu ngoặc kép trong trường được nhân đôi.

Bất kỳ giải pháp chung nào hỗ trợ "các chuyến đi khứ hồi" nhất định sẽ hơi phức tạp. Lý do chính tại sao giải pháp được trình bày ở đây phức tạp hơn người ta có thể mong đợi là do cột thứ ba được thêm vào, một phần để giúp dễ dàng phân biệt giữa số nguyên và chuỗi có giá trị tích phân, nhưng chủ yếu là vì nó giúp dễ dàng phân biệt giữa kích thước-1 và kích thước -2 mảng được tạo bởi jq's --stream quyền mua. Không cần phải nói, có những vấn đề khác có thể được giải quyết; số lượng cuộc gọi đến jq cũng có thể bị giảm.

Giải pháp được trình bày dưới dạng một kịch bản thử nghiệm để kiểm tra yêu cầu khứ hồi đối với một trường hợp thử nghiệm đang nói:

#!/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)

Đây là CSV sẽ được tạo ra bởi json | tocsv , ngoại trừ SO dường như không cho phép NUL theo nghĩa đen, vì vậy tôi đã thay thế nó bằng \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. $ push trong MongoDb không hoạt động?

  2. Làm thế nào để chuyển đổi BSON ::Dấu thời gian sang thời gian ruby ​​và ngược lại

  3. MongoDB - ví dụ tham chiếu thủ công

  4. Chạy db.repairDatabase () từ mongodb-native trong node.js

  5. MongoDB sao chép một trường vào một bộ sưu tập khác bằng khóa ngoại