Rechercher

Artículo
· 8 oct, 2024 Lectura de 5 min

FHIR Object Model 简介

挑战

在使用FHIR进行开发的过程中,我们会面对海量的FHIR规范中定义的数据结构,具体来说在FHIR规范中定义了超过150个资源、700多个资源内元素。每个定义里都包括了对自身结构的描述以及数据约束、数据绑定值集等。对于一个开发人员要记住这些内容非常困难。

同时FHIR数据,特别是Json格式的FHIR数据是典型的“有向图”结构,它的资源中嵌套元素定义、集合以及复杂的资源间“关系”,在这些复杂结构的数据间导航并操作,非常困难。

解决方案

在InterSystems IRIS for Health 2024.1之前,我们会将FHIR数据以Json文档的方式载入 %DynamicAbstractObject,例如下面的代码

   set dynObject1 = ##class(%DynamicObject).%New()
   set dynObject1.SomeNumber = 42
   set dynObject1.SomeString = "a string"
   set dynObject1.SomeArray = ##class(%DynamicArray).%New()
   set dynObject1.SomeArray."0" = "an array element"
   set dynObject1.SomeArray."1" = 123
   set dynObject2 = {"SomeNumber":42,"SomeString":"a string"}
   set dynObject2.SomeArray = ["an array element",123]
   
   write "object 1: "_dynObject1.%ToJSON(),!,"object 2: "_dynObject2.%ToJSON()

可以看到这样的处理有下面不方便的地方:

  • 只能使用自己的方式解析、导航FHIR结构
  • 不能从IDE中获取提示信息
  • 没有数据类型安全
  • 没有上下文敏感的文档
  • 没有调试debug的支持

在InterSystems IRIS for Health 2024.1版本之后,引入了FHIR 对象模型。

FHIR 对象模型概览

在 HS.FHIRModel.R4 包下,每一个FHIR R4资源都对应一个ObjectScript类。比如 HS.FHIRModel.R4.AllergyIntolerance类对应于 AllergyIntolerance 资源。这些类通过为资源和组成元素提供一个共享的、可预测的数据结构和方法框架,简化了开发过程。

这样的结构,在VS Code环境下,会给出很好的提示

下面具体举例如何使用FHIR 对象模型:

1. 获取数据

按索引获取有序序列中的值

 Set patientName = patient.name.get(0)

获取嵌套定义中的值

 Set patientIdValue = patient.identifier.get(0).get(“value”)
 Set patientCity = patient.address.get(0).city

在获取数据前判断键key是否存在

 If patient.name.get(0).contains("family") {
     Set familyName = patient.name.get(0).get(“family”) 
 }

2. 更新数据

添加新的键值对

 Do patient.name.get(0).put("use","official")

更新存在的值

 Do observation.put("status","final")

3. 添加对象的引用

 Set claim = ##class(HS.FHIRModel.R4.Claim).%New()
 Do claim.IncludeType()
 Do claim.type.IncludeCoding()

4. 导航对象

 Set contactItr = patient.contact.get(0).telecom.iterator()
 While contactItr.hasNext() {
    Set contact = contactItr.next().value
    if contact.system = "phone" {
        Write !, contact.value
    }
 }

5 读取JSON格式 FHIR 数据

 Set rType = dao.resourceType
 Set cls = $CLASSMETHOD("I4H.FhirR4."_rType,"fromDao",dao)

6. 将FHIR 数据输出为 JSON 格式

 Set newDao = cls.toDao()

转为字符串

 Set payload = cls.toString()

7. 创建新的 FHIR 元素

 Do claim.IncludeType()
 Do claim.type.IncludeCoding()
 Set coding = ..MakeCoding("http://terminology.hl7.org/CodeSystem/claim-type","institutional")
 Do claim.type.coding.add(coding)

8. “图” 结构查询引擎

 Set key = "system"
 Set value = "email"
 Set query = "$[*]?(@."_key_"=='"_value_"')"
 Set email = doctor.telecom.apply(query)

更多资料

FHIR Object Model 在线文档:https://docs.intersystems.com/irisforhealth20242/csp/docbook/DocBook.UI.Page.cls?KEY=HXFHIR_data#HXFHIR_data_classes

 

下面是一个完整的创建患者资源的例子

ClassMethod MakeCoding(system As %String, code As %String, display As %String = "") As HS.FHIRModel.R4.Coding
{
    Set rec = ##class(HS.FHIRModel.R4.Coding).%New()
	Set rec.system = system
	Set rec.code = code
	If (display'="") Set rec.display = display
	Return rec
}

// Create a Patient using FHIR Object Model classes from R4 and then post
// this patient on the FHIR server
ClassMethod CreatePatient(ident As %String) As %Status
{
   #dim patient As HS.FHIRModel.R4.Patient
   Set patient = ##class(HS.FHIRModel.R4.Patient).%New()
   Do patient.IncludeName()
   Set name = patient.name.MakeEntry()
   Set firstName = "John"
   Do name.IncludeGiven()
   Do name.given.add(firstName)
   Set name.family = "Doe"
   Do patient.name.add(name)

    If patient.name.get(0).contains("family") {
    Set fName = patient.name.get(0).get("family") 
    }

    Do patient.name.get(0).put("use","official")

   Set patient.gender = "male"
   Set patient.birthDate = "1985-05-15"
   Do patient.IncludeAddress()
   Set addr = patient.address.MakeEntry()
   Do addr.IncludeLine()
   Set line1 = "123 Main Street"
   Do addr.line.add(line1)
   Set addr.city = "Boston"
   Set addr.state = "MA"
   Set addr.postalCode = "02111"
   Do patient.address.add(addr)

   Set address = ##class(HS.FHIRModel.R4.Address).%New()
   Do patient.put("address", address)

   Do patient.IncludeContact()
   Set contact = patient.contact.MakeEntry()

   Do contact.IncludeTelecom()
   Set telecom = contact.telecom.MakeEntry()
   Set telecom.system = "phone"
   Set telecom.value = "555-555-5555"
   Set telecom.use = "mobile"
   Do contact.telecom.add(telecom)
   Do patient.contact.add(contact)

   Set contactItr = patient.contact.get(0).telecom.iterator()
   While contactItr.hasNext() {
    Set contact = contactItr.next().value
    if contact.system = "phone" {
        Write !, contact.value
    }
   }

   Do patient.IncludeIdentifier()
   Set id = patient.identifier.MakeEntry()
   Set coding = ..MakeCoding("http://terminology.hl7.org/CodeSystem/v2-0203", "MR")
   Set id.type = coding
   Set id.value = ident
   Do patient.identifier.add(id)
   Set patientJSON = patient.toDao()



   Set service = ##class(HS.FHIRServer.Service).EnsureInstance(1)
   Do service.interactions.Add(patientJSON)
   Return $$$OK
}
Comentarios (0)1
Inicie sesión o regístrese para continuar
Artículo
· 8 oct, 2024 Lectura de 4 min

iris-DataViz: Aplicación de análisis y visualización de datos al estilo de Tableau con función de arrastrar y soltar

image

Hola Comunidad,

En este artículo, os presentaré mi aplicación iris-DataViz.

iris-DataViz es una aplicación de análisis y visualización de datos exploratorios basada en Streamlit que aprovecha la funcionalidad de IRIS embebido en Python y SQLAlchemy para interactuar con IRIS, así como la biblioteca de Python PyGWalker para el análisis de datos y la visualización de datos. PyGWalker (Python Graphic Walker) es una biblioteca de visualización de datos interactiva creada para Python, que tiene como objetivo llevar la facilidad y funcionalidad de la visualización al estilo de Tableau con arrastrar y soltar a los entornos de Python.

Características de la aplicación

  • Visualización de arrastrar y soltar
  • Manipulación y limpieza de los datos dentro de la visualización
  • Amplia gama de tipos de gráficos:
  • Exploración interactiva de datos
  • Agregación y agrupación interactivas.
  • Visualizaciones exportables
  • Resumen automático de datos
  • Campos calculados / computados
  • Soporte para datos categóricos, numéricos y temporales
  • Leyendas y filtros interactivos
  • Generación interactiva de informes
  • Soporte de datos geoespaciales


Vista general de la aplicación

La aplicación ya incluye importados datos relacionados con coches. Para ver los datos, navegad al Portal de Gestión de SQL y visualizad los datos utilizando el siguiente comando SQL:

SELECT
Make, Model, Year, EngineFuelType, EngineHP,
EngineCylinders, TransmissionType, Driven_Wheels, 
NumberofDoors, MarketCategory, VehicleSize, 
VehicleStyle, highwayMPG, citympg, Popularity, MSRP
FROM DataViz.CarsInfo

image

Para ejecutar la aplicación, navegad a http://localhost:8051. Seleccionad el espacio de nombres, el esquema y la tabla. Haced clic en la pestaña de Datos para analizar los datos.


image

Seleccionad la pestaña de Visualización, arrastrad las columnas deseadas al eje X y al eje Y, y seleccionad el tipo de gráfico que queráis.
image

Fragmento de código de la aplicación

A continuación, se presenta el código de ObjectScript invocado desde Python embebido para obtener los espacios de nombres de IRIS:

Class dc.DataViz.Util Extends %RegisteredObject
{
ClassMethod getNameSpaces() As %String
{
 //init sql statement   
 set statement=##class(%SQL.Statement).%New()
 //Prepare Class Query
 set status=statement.%PrepareClassQuery("%SYS.Namespace","List")
 //Check the Error
 if $$$ISERR(status) 
 { 
    do $system.OBJ.DisplayError(status) 
 }
 //Execute the statement
 set resultset=statement.%Execute()
 set results = "1"
 while resultset.%Next() {
	//zw resultset    
    if results = "1" {
	    set results = resultset.%Get("Nsp")
	    }
    else
    {
    	set results = results _ "," _ resultset.%Get("Nsp")
    }
 }
 return results
}
}

Código de Python embebido que invoca el código de ObjectScript:

  import iris
  ns = iris.cls('dc.DataViz.Util').getNameSpaces()
  namespaces = ns.split(",")

El código a continuación obtendrá la lista de esquemas y tablas:

 def get_schema(self):
        #Establish IRIS Connection    
        with self.engine.connect() as conn:
            with conn.begin():     
                sql = text(""" 
                    SELECT distinct TABLE_SCHEMA
                    FROM INFORMATION_SCHEMA.TABLES                   
                    WHERE TABLE_TYPE='BASE TABLE'       
                    order by TABLE_SCHEMA
                    """)
                results = []
                try:
                    #Fetch records into results variable
                    results = conn.execute(sql).fetchall()
                    schemas="0"
                    for element in results:                                 
                       if schemas == "0":
                           schemas = element[0]
                       else:
                           schemas = schemas+","+element[0]
                except Exception as e:
                    print(e)
                    
        return schemas

    def get_tables(self,schema):
        #Establish IRIS Connection       
        with self.engine.connect() as conn:
            with conn.begin():     
                sql = text(""" 
                    SELECT TABLE_NAME
                    FROM INFORMATION_SCHEMA.TABLES                   
                    WHERE TABLE_TYPE='BASE TABLE'
                    AND TABLE_SCHEMA = :schema
                     order by TABLE_NAME
                    """).bindparams(schema=schema)            
                results = []
                try:
                    #Fetch records into results variable
                    results = conn.execute(sql).fetchall()                  
                    tables="0"
                    for element in results:                                 
                       if tables == "0":
                           tables = element[0]
                       else:
                           tables = tables+","+element[0]
                except Exception as e:
                    print(e)
                    
        return tables

Para más detalles, por favor, visitad la página de la aplicación iris-DataViz en Open Exchange.

Gracias.

Comentarios (0)1
Inicie sesión o regístrese para continuar
Artículo
· 8 oct, 2024 Lectura de 9 min

GitLab を使用した InterSystems ソリューションの継続的デリバリー - パート X: コード以外の話

約 4 年のギャップを経て、私の CI/CD シリーズが帰ってきました! 長年にわたり、InterSystems の数社のお客様と連携し、様々なユースケースに対応する CI/CD パイプラインを開発してきました。 この記事で紹介する情報が誰かのお役に立てられれば幸いです。

この連載記事では、InterSystems テクノロジーと GitLab を使用したソフトウェア開発の様々な可能なアプローチを取り上げています。

取り上げたいトピックは広範にありますが、今回は、コードを超えた内容についてお話ししましょう。構成とデータについてです。

Comentarios (0)1
Inicie sesión o regístrese para continuar
Anuncio
· 8 oct, 2024

Gagnants du Premier Concours d'Articles Techniques !

Bonjour les Développeurs !

Nous avons de nouveaux articles super intéressants à lire grâce aux merveilleux participants du Concours d'Articles Techniques InterSystems !

🌟 4 articles incroyables 🌟

Et maintenant, il est temps d'annoncer les gagnants !

Découvrons les gagnants et leurs articles :

⭐️ Prix des experts – gagnants sélectionnés par les experts d'InterSystems :

🥇 1ère place et le choix entre Apple Watch SE GPS / Lego NINJAGO® City Gardens / Lego Dungeons & Dragons: Red Dragon's Tale : Utilisation des bons types de stream dans un environnement mirroré par @Matthieu LAURENT 

🥈 2ème place et le choix entre SteelSeries Arctis Nova 7X / AirPods (3ᵉ génération) / Lego Hogwarts™ Castle: The Great Hall : Tests unitaires avec VSCode et une version de IRIS antérieure à 2023.3 par @Robert Barbiaux 

🥉 3ème place et le choix entre Samsonite Classic Business Perfect Fit / Lego Spider-Man Final Battle / Huawei Watch Fit SE : Injection SQL - une menace vaincue ? par @Iryna Mykhailova 

⭐️ Prix de la communauté et le choix entre Samsonite Classic Business Perfect Fit / Lego Spider-Man Final Battle / Huawei Watch Fit SE – gagnant sélectionné par les membres de la Communauté, article avec le plus de likes :

🏆 Utilisation des bons types de stream dans un environnement mirroré par @Matthieu LAURENT 

Félicitons ces héros qui ont participé au Concours d'Articles Techniques et qui recevront chacun une gourde en remerciement de leur participation :

@Robert Barbiaux 
@Matthieu LAURENT 
@Robert Cemper
@Iryna Mykhailova 

MERCI À TOUS ! Vous avez apporté une contribution incroyable à notre Communauté de Développeurs !


Les prix sont en cours de production. Nous contacterons tous les participants lorsqu'ils seront prêts à être expédiés.

5 comentarios
Comentarios (5)4
Inicie sesión o regístrese para continuar
Pregunta
· 8 oct, 2024

Performance tuning techniques - Emmanuel Katto Uganda

Hi everyone, My name is Emmanuel Katto. What performance tuning techniques have you found most effective when working with InterSystems IRIS? Any specific metrics to monitor?

 

I look forward to your tips/suggestions.

Thanks in advance!

Best,

Emmanuel Katto

4 comentarios
Comentarios (4)4
Inicie sesión o regístrese para continuar