จัดการ JSON ซ้อนกันลึกด้วย jq streams แบบมือโปร
วิธีแก้ปัญหาไฟล์ JSON ขนาดใหญ่และซ้อนกันหลายชั้นด้วยฟังก์ชัน tostream และ fromstream ใน jq โดยไม่ต้องเขียนสคริปต์ Python ซับซ้อน

ภาพประกอบจากคลังภาพสต็อก ไม่ใช่ภาพจากเหตุการณ์จริง
- ไฟล์ JSON ขนาดใหญ่และซ้อนกันลึกมักสร้างปัญหาเมื่อต้องการลบฟิลด์เฉพาะเจาะจง
- ฟังก์ชัน tostream ช่วยแปลงเอกสารทั้งหมดเป็นสตรีมคู่ [path, value] เพื่อการกรองที่ง่ายขึ้น
- ฟังก์ชัน fromstream ทำหน้าที่ประกอบสตรีมที่ผ่านการกรองแล้วกลับมาเป็นไฟล์ JSON ตามเดิม
- วิธีนี้ช่วยประหยัดเวลาและลดความซับซ้อน แทนการเขียนสคริปต์ Python เพื่อวนลูป dict แบบเรียกซ้ำ
นักพัฒนาซอฟต์แวร์หลายคนคงเคยเผชิญกับปัญหาไฟล์ JSON ขนาดใหญ่ เช่น สเปก OpenAPI ขนาด 500KB ที่ต้องการลบฟิลด์คำอธิบาย (description) ทุกตัวที่ซ้อนอยู่ตามความลึกต่างๆ แม้ว่าเส้นทางปกติอย่าง .. | .description? จะช่วยให้อ่านข้อมูลได้ แต่การลบข้อมูลออกกลับไม่ใช่เรื่องง่าย เนื่องจากเส้นทางดังกล่าวไม่ได้บอกตำแหน่งที่จะนำผลลัพธ์กลับไปวาง
ทางออกของปัญหานี้คือการใช้งาน tostream และ fromstream ที่มีอยู่ใน jq ซึ่งจะช่วยแปลงเอกสารทั้งหมดให้อยู่ในรูปของสตรีมคู่ [path, value] ตัวอย่างเช่น:
- jq 'tostream' spec.json จะแสดงผลลัพธ์เป็น [["openapi"], "3.0.1"]
- [["info", "title"], "Petstore"]
- [["info", "description"], "This is a sample server..."]

ภาพประกอบจากคลังภาพสต็อก ไม่ใช่ภาพจากเหตุการณ์จริง
เมื่อข้อมูลถูกแปลงเป็นสตรีมแล้ว เราสามารถใช้เครื่องมือทั่วไปอย่าง grep หรือคำสั่ง select ของ jq เพื่อกรองข้อมูลออกตามต้องการ ก่อนจะส่งต่อไปยัง fromstream เพื่อประกอบร่างเอกสารใหม่ในบรรทัดเดียว เช่นคำสั่ง jq 'tostream | select(.[0][-1] != "description") | fromstream' spec.json > spec-clean.json ซึ่งสามารถลบฟิลด์ description ทุกระดับความลึกได้อย่างรวดเร็ว รูปแบบสตรีมนี้ประกอบด้วย [path_array, leaf_value] ทำให้ .[0][-1] สามารถเข้าถึงคีย์สุดท้ายในเส้นทางนั้นได้ทันที
ฟีเจอร์สตรีมของ jq มีให้บริการตั้งแต่เวอร์ชัน 1.6 ในปี 2019 แม้จะไม่ใช่ฟีเจอร์ใหม่แกะกล่อง แต่ก็ยังถูกใช้งานน้อยกว่าที่ควรจะเป็น การทำความเข้าใจโครงสร้างข้อมูลแบบสตรีมไม่เพียงแต่ช่วยแก้ปัญหาไฟล์ JSON ที่ซ้อนกันลึกได้อย่างรวดเร็ว แต่ยังช่วยลดการพึ่งพากอาศัยภาษาโปรแกรมมิ่งทั่วไปอย่าง Python หรือ Node.js สำหรับงานจัดการข้อมูลขนาดเล็กในระบบอัตโนมัติหรือ Bash script อีกด้วย
เทคนิคนี้ได้รับการพิสูจน์แล้วว่าใช้งานได้จริง โดยผู้เขียนบทความระบุว่าเคยนำไปใช้จัดการกับไฟล์ Kubernetes CRD manifest ขนาด 2MB เพื่อลบส่วนขยาย x-kubernetes-* ทั้งหมด ซึ่งใช้เวลาประมวลผลเพียง 3วินาทีเท่านั้น เปรียบเทียบกับการเขียนสคริปต์ Python ที่ต้องใช้งานฟังก์ชันเรียกซ้ำ (recursive dict walking) ที่ซับซ้อนกว่ามาก
ที่มา: Dev.to
พบข้อมูลผิดพลาดในบทความนี้? แจ้งปัญหาบทความนี้
ความคิดเห็น
แสดงความคิดเห็น