การใช้ Fixed Pattern และ Fixed Value ใน US-Core และ IPS

ในช่วงสัปดาห์ที่ผ่านมา ผมพยายามทำความเข้าใจและหาข้อสรุปให้ตนเองว่าเวลาเราทำ FHIR Profile เมื่อไหร่ควรใช้ fixed value และเมื่อไหร่ควรใช้ fixed pattern ก็เลยลองดูตัวอย่างจากใน US-Core และ International Patient Summary (IPS) มาครับ สรุปว่าทั้งสอง implementation guide (IG) ทำแบบนี้ครับ

(Cover Photo by Praewthida K on Unsplash)

1. ใช้ fixed value น้อย

ส่วนใหญ่จะใช้ fixedCode หรือ fixedUri สำหรับ data type ต่าง ๆ ที่มีการใช้ code, system

US-Core มีใช้แค่ 2 ที่

  • Vital Signs Profile โดยใช้ใน slicing ของ Observation.category และ profile ย่อยอื่น ๆ ในกลุ่มนี้ก็ derive ไปจาก profile นี้ (จริง ๆ อันนี้ก็เป็นวิธี slice เดียวกันกับ vital signs profile ของ FHIR core)
  • ใช้ในการระบุ code และ system ของ Quantity ใน Observation ส่วนใหญ่ก็คือ vital signs profile และลูก ๆ นี่แหละครับ เช่นด้านล่างนี้คือ blood pressure profile ส่วน diastolic

IPS มีใช้แค่ 2 ที่เช่นกัน

  • ใช้ในการระบุ system ของ profile ของ datatype Quantity และ SimpleQuantity

2. ใช้ pattern เป็นหลักในการ discriminate แล้ว fixed pattern ใน slice

ถ้าลองดูในทั้งสอง IG จะเห็นว่าเขาไปท่านี้เยอะมาก แต่โดยหลัก ๆ ก็มี data type อยู่ 3 ประเภทที่เขาจะ fixed pattern ได้แก่

  • CodeableConcept อันนี้พบบ่อยที่สุดแล้ว เช่น ใน Provenance profile นี้ จะเห็นว่า type เป็น CodeableConcept ที่แต่ละ slice จะมีการบังคับ coding อย่างน้อย 1 element (ข้างในก็จะมี system และ code)

ถ้าไปดูที่ element หลัก จะพบว่า slice ด้วย pattern โดยมี path เป็น type (จะกล่าวถึงในหัวข้อถัดไป)

  • Identifier เป็นอันที่พบบ่อยรองลงมา เช่น Practitioner, Organization เช่น ด้านล่างนี้จะเห็นว่า slice ของ NPI บังคับ pattern โดยกำหนดค่าของ system

คำถามที่ผมยังต้องหาคำตอบเพิ่ม -> การทำ fixed pattern ใน slice ของ identifier แบบนี้ ต่างอย่างไรกับการทำ fixed value ใส่ element ลูกของ slice ? เช่น แทนที่เราจะไป fixed pattern ที่ Practitioner.identifier:NPI เราก็ไป fixed value ที่ Practitioner.identifier:NPI.system เลยได้หรือไม่ โดยไม่ต้อง fixed pattern

  • Coding อันนี้ผมเห็นแค่ที่เดียวคือที่ US Core Pulse Oximetry Profile เป็นการ fix Coding สองค่า ภายใน element ที่เป็น CodeableConcept

เสริม: discriminator ที่ใช้ในทั้งสอง IG

น่าสนใจว่าทั้งสอง IG เลือกใช้ discriminator หลัก ๆ แค่ 3 แบบนี้เท่านั้น (ไม่รวม value ใน vital signs)

pattern

เนื่องจากข้อมูลที่แลกเปลี่ยนใน FHIR ส่วนใหญ่มักจะเป็น CodeableConcept ซึ่งพอเป็น data type นี้ เขาจึงมักจะเลือกใช้ discriminator เป็น pattern ดังที่ได้กล่าวไปก่อนหน้านี้ และโดยส่วนใหญ่มักจะใช้ path เป็น $this ด้วยครับ เพราะ slice ที่ตัว element เอง เช่น Observation.category อันนี้ สังเกตว่า slice by pattern ที่ path คือ $this

หรือลองดู IPS Immunization นี้ก็ได้ครับ จะเห็นว่า vaccineCode และ protocolApplied.targetDisease ก็ slice ด้วย pattern ที่ path คือ $this

type

มักใช้กับพวกที่เลือก data type ได้หลายแบบ เช่น Observation.value[x] หรือ Medication.ingredient.item[x]

คำถามที่ผมยังตอบไม่ได้: data พวกนี้มี maximum cardinality เป็น 1 (มีได้ค่าเดียว) ทำไมถึงเลือกทำ slice แล้วค่อยมาจำกัด type เอาใน slice แทนที่จะจำกัด type ตั้งแต่ element หลักเลย

profile

อันนี้มีใช้ใน IPS 2 ที่ ได้แก่ DiagnosticReport และ Composition.section.entry น่าสนใจเหมือนกันว่าทำไมถึงเลือกใช้วิธีนี้ อีกอย่างคือ US-Core ก็ไม่ได้มี profile ไหนที่ใช้วิธีนี้

หมายเหตุ: ใน FHIR spec แบบว่าการ discriminate ด้วยวิธีนี้ต้องใช้ process สูงสุด (reference)

ก็หมดแล้วครับ ผมว่าก็พอได้ไอเดียว่าถ้าทำ profile เองควรจะทำแบบไหน กล่าวโดยสรุปคือ

  1. ถ้าจะทำ slicing เน้นใช้ pattern เป็น discriminator แล้วก็ไป fixed pattern ใน slice (หลัก ๆ คือ CodeableConcept กับ Identifier)
  2. พวก primitive value ใช้ fixed value ได้ รวมถึงพวก system, code ของ Quantity
  3. เรื่อง discriminate ด้วย type กับ profile นี่ผมยังไม่ค่อยแม่น

ส่วนพวกคำถามที่ผมติดค้างไว้เดี๋ยวไว้ได้คำตอบแล้วมาแชร์ครับ

Leave a Reply

Your email address will not be published. Required fields are marked *