Article Tomoko Furuzono · Nov 6, 2025 2m read

InterSystems FAQ rubric

When exporting using the Export() method of the %Library.Global class, if the export format (fourth argument: OutputFormat) is set to 7, "Block format/Caché block format (%GOF)," mapped globals cannot be exported (only globals in the default global database of the namespace are exported). To export mapped globals in "Block format/Caché block format (%GOF)," specify the database directory to which you want to map them in the first parameter of %Library.Global.Export().

An example of execution is shown below. 

0
0 24
Announcement Brenna Quirk · Nov 6, 2025

Hi, Community!

Looking for an efficient way to allow providers to see whether prior authorization is required? See how the Coverage Requirements Discovery (CRD) module of the InterSystems Payer Services ePrior Authorization solution can help:

Coverage Requirements Discovery

<iframe allowfullscreen="" frameborder="0" height="360" src="https://www.youtube.com/embed/MY1If1CEjrM?utm_source=youtube&utm_medium=social&utm_campaign=MY1If1CEjrM" width="640"></iframe>

In this video, you will learn how CRD allows providers to connect an EHR to a payer system to evaluate coverage.

Watch the full playlist on YouTube(10m).

0
0 19
Question Norman W. Freeman · Nov 5, 2025

The following regex is matching while I think it should not :

write$match("♥","\?") //print '1' (unexpected)

It should only match the '?' character. I think what happen is the ♥ character got converted to '?' (as it's not within regular ascii range) before being validated by the regex engine.

In fact, this give a clue about what happen : 

write$char($ascii("♥")) //print '?'

Is this an IRIS well known limitation, is there workarounds ? Should I report it to InterSystems ?

7
0 64
Article Ashok Kumar T · Oct 20, 2025 11m read

What is XML?

XML(eXtensible Markup Language) is a flexible, text-based, andplatform-independentformat used to store and transport data in a well-structured way that is both human- and machine-readable. XML permits users to define custom tags to describe the meaning and organization of their data. For example: <book><title>The Hitchhiker's Guide</title></book>.

3
5 163
Question Kevin Mayfield · Nov 6, 2025

I have a quite complex FHIR Implementation Guide (IG) which is based on several other FHIR IGs. It's likely the versions of IGs conflict with each other.
From what I understand, I would need to load in all the other FHIR IG's first? 
I don't actually need FHIR profiles to be in our FHIR Repository - I'm just after terminology and the examples for our test system.
Is it possible to load a FHIR IG just as data? (I think I mean here, ignore the FHIR profiles and dependencies between them)

1
0 24
Article Ashok Kumar T · Feb 17, 2025 6m read

What is JWT?

JWT (JSON Web Token) is an open standard (RFC 7519) that offers a lightweight, compact, and self-contained method for securely transmitting information between two parties. It is commonly used in web applications for authentication, authorization, and information exchange.

A JWT is typically composed of three parts:

1. JOSE (JSON Object Signing and Encryption) Header
2. Payload
3. Signature

These parts are encoded in Base64Url format and concatenated with dots (.) separating them.

Structure of a JWT

Header

{ "alg": "HS256", "typ": "JWT"}

Payload

3
8 389
InterSystems Official Carmen Logue · Nov 5, 2025

InterSystems IRIS Adaptive Analytics version 2025.4.1 is now available from the InterSystems Software Distribution page.  This release includes AtScale 2025.4.1 and is compatible with the existing  Adaptive Analytics User-Defined Aggregate Function (UDAF) file - 2024.1.  New features included in AtSCale's 2025 releases include:

  • Several MDX improvements to better handle null values and semi-additive measures like year-to-date.
  • New parameters to enable setting the visibility of calculations and calculation groups in BI tools.
  • Support for inbound query crossjoins that return empty cells
0
0 30
Article Pravin Barton · May 1, 2020 1m read

ObjectScript doesn't include any built-in method for appending one JSON dynamic array to another. Here's a code snippet I use that's equivalent to the JavaScript concat() method.

Call it with any number of arguments to concatenate them into a new array. If an argument is a dynamic array, its elements will be added. Otherwise the argument itself will be added.

ClassMethod ConcatArrays(pArgs...) As %DynamicArray
{
	set outArray = ##class(%DynamicArray).%New()
	for i=1:1:pArgs {
		set arg = pArgs(i)
		if ($IsObject(arg) && arg.%IsA("%DynamicArray")) {
			set iter = arg.%GetIterator()
			while iter.%GetNext(.key, .value) {
				do outArray.%Push(value)
			}
		} else {
			do outArray.%Push(arg)
		}
	}
	return outArray
}

Feel free to let me know if there's a better way to do this!

6
4 942
Announcement Olga Zavrazhnova · Nov 5, 2025

Let’s shine a light on the amazing authors and contributors of our October Article Bounty! 💙
Huge thanks to everyone who joined in and shared their knowledge.

A special mention goes to those who created brand-new articles and shared their expertise — each received 5,000 points 🎉

1. @Robert Cemper >> "Sample for Beginners with Streams in IRIS"
2. @Vachan C Rannore >> "What I’ve Learned from Multiple Data Migrations"
3. @Harshitha  >> "Tips on handling Large data"
And also to those who joined the challenge and helped us in the search for interesting articles (each received 30 points 🙌):

0
1 30
Article Iskander Shangareev · Feb 14, 2025 2m read

CCR users can now take advantage of an enhanced syntax for substituting pre-defined tokens with live URL links within phase-related text fields. In addition to the existing <env> token which automatically updates to reflect the Environment of the relevant CCR Record, CCR now introduces three new keywords: <smp> , <smpPrefix> , and <homepage>.

3
0 200
Article Theo Stolker · Feb 17, 2025 2m read

For one of our customers I had to integrate with the AFAS imageconnector endpoint /imageconnector/{imageId}?format={format}. This endpoint returns in a json message with the image as a base64-encoded string property, in addition to the mimetype for the image:

/// Image Object
Class Mycustomer.Model.AfasGet.Image Extends (%SerialObject, %XML.Adaptor, %JSON.Adaptor)
{
/// file data (base64 encoded)
Property Filedata As %String(%JSONFIELDNAME = "filedata");

/// MimeType e.g. "image/jpeg"
Property MimeType As %String(%JSONFIELDNAME = "mimetype");
}

In the Message class, we tried handling this like:

Property Image As Mycustomer.Model.AfasGet.Image;

/// AFAS GetImage response
/// get /imageconnector/{imageId}?format={format}
Method LoadFromResponse(httpResponse As %Net.HttpResponse, caller As %String = "") As %Status
{
	Set sc = $$$OK

	If $$$LOWER($Piece(httpResponse.ContentType,";",1))="application/json",httpResponse.StatusCode = "200" {
		set ..Image = ##class(Mycustomer.Model.AfasGet.Image).%New()
		set ..status = ..Image.%JSONImport(httpResponse.Data)
	}

	Return sc
}

This all worked fine until at some point the size of the filedata became larger than the $$$MaxStringLength (3641144), in which case a MAXSTRING exception was raised.

The logical next step was to change the type of the filedata property to %Stream.GlobalCharacter:

/// Image Object
Class Mycustomer.Model.AfasGet.Image Extends (%SerialObject, %XML.Adaptor, %JSON.Adaptor)
{
/// file data (base64 encoded)
Property Filedata As %Stream.GlobalCharacter(%JSONFIELDNAME = "filedata");

/// MimeType e.g. "image/jpeg"
Property MimeType As %String(%JSONFIELDNAME = "mimetype");
}

But that didn't work, %JSONImport() would still raise a MAXSTRING error.

I then tried Python, but as I am not a python wizard, I gave up on that route eventually.

Thanks to the answer from https://community.intersystems.com/user/steven-hobbs on https://community.intersystems.com/post/maxstring-trying-read-string-json-object#comment-250216, I then learned that it is possible and straightforward to retrieve json string properties into a stream using image.%Get("filedata", , "stream")):

Method LoadFromResponse(httpResponse As %Net.HttpResponse, caller As %String = "") As %Status
{
	Set sc = $$$OK

	If $$$LOWER($Piece(httpResponse.ContentType,";",1))="application/json",httpResponse.StatusCode = "200" {
		set ..Image = ##class(Mycustomer.Model.AfasGet.Image).%New()
		set image = {}.%FromJSON(httpResponse.Data)
		set ..Image.MimeType = image.mimetype
		set ..Image.Filedata = ##class(%Stream.GlobalCharacter).%New()
		do ..Image.Filedata.CopyFrom(image.%Get("filedata", , "stream"))
	}

	Return sc
}

I am still puzzled as how I would be able to instruct the %JSON.Adaptor class and use the built-in logic to map to a stream. If there is anyone out there that knows how to do this, please let me know!

3
1 283
Article Mario Sanchez Macias · Feb 19, 2025 4m read

 

So, you checked your server and saw that IRISTEMP is growing too much. There's no need to panic. Let’s investigate the issue before your storage runs out.

Step 1: Confirm the IRISTEMP Growth Issue

Before assuming IRISTEMP is the problem, let’s check its actual size.

Check the Free Space

Run the following command in the IRIS terminal:

%SYS>do ^%FREECNT

When prompted, enter:

Database directory to show free space for (*=All)? /<your_iris_directory>/mgr/iristemp/
4
4 338
Article Laura Blázquez García · Feb 23, 2025 4m read

When we create a FHIR repository in IRIS, we have an endpoint to access information, create new resources, etc. But there are some resources in FHIR that probably we wont have in our repository, for example, Binary resource (this resource returns a document, like PDF for example).

I have created an example that when a Binary resource is requested, FHIR endpoint returns a response, like it exists in the repository. 

7
6 336
Article Rob Tweed · Feb 26, 2025 6m read

Introduction

My guess is that most IRIS developers create their applications using its native ObjectScript language or, if using an external language, then most likely using either Java, Python or perhaps C++.

I suspect that only a minority have considered using JavaScript as their language of choice, which, if true, is a great shame, because, In my opinion and experience, JavaScript is the closest equivalent to ObjectScript in terms of its ability to integrate with the IRIS's underlying multi-dimensional database. 

1
2 270
Article Corentin Blondeau · Feb 24, 2025 4m read

Hello
This article follows up on the question I had asked the community UDP Adapter not working
In this article, I will present to you
1) What is "UDP"?
2) The current state of Iris with UDP
3) My solution with the UDP adapter


1) What is "UDP"?

UDP stands for User Datagram Protocol. It is one of the core protocols of the Internet Protocol (IP) suite, used for transmitting data over a network. Here are some key features of UDP:

4
4 257
Article sween · Nov 4, 2025 11m read

Mirror Your Database Across the Galaxy with Seeding

Hello cpf fans!  This distraction I used the "seed" capability in IRIS to provision an entire IrisCluster mirror, 4 maps wide with compute starting from an IRIS.DAT in a galaxy far far away.  This is pretty powerful if you have had a great deal of success with a solution running on a monolithic implementation and want it to scale to the outer rim with Kubernetes and the InterSystems Kubernetes Operator.  Even though my midichlorian count is admittely low, I have seen some hardcore CACHE hackers shovel around DATS, compact and shrink and update their ZROUTINES, so this same approach could also be helpful shrinking and securing your containerized workload too.  If you squint and feel all living things around you,  you can see a glimpse of in place (logical) mirroring in the future as a function of the operator and a migration path to a fully operational mirrored Death Star as the workload matures.


0
0 31
Article Timothy Scott · Feb 28, 2025 7m read

High-Performance Message Searching in Health Connect

The Problem

Have you ever tried to do a search in Message Viewer on a busy interface and had the query time out? This can become quite a problem as the amount of data increases. For context, the instance of Health Connect I am working with does roughly 155 million Message Headers per day with 21 day message retention. To try and help with search performance, we extended the built-in SearchTable with commonly used fields in hopes that indexing these fields would result in faster query times. Despite this, we still couldn't get some of these queries to finish at all.

More Info Defining a Search Table Class.

image

For those of us working as HL7 integrators, we know that troubleshooting and responding to issues on a day-to-day basis is a huge part of our role. Quickly identifying and resolving these issues is critical to ensuring that we are maintaining the steady and accurate flow of data. Due to the poor search performance, we would have to gather very detailed information about each specific issue to find examples in Health Connect. Without a very narrow time frame (within a few minutes), we often were unable to get Message Viewer search to return any results before timing out. This caused a significant delay both in determining what the actual problem was and resolving it moving forward.

The Solution

This was not acceptable, so we had to find a solution in order to best serve our customers. Enter WRC.

image

We created a ticket, and I am happy to report a fix was identified. This fix involved going through our custom SearchTable fields and identifying which fields were not unique enough to warrant being treated as an index by the Message Viewer search.

For example, in our environment, MSH.4 (or FacilityID) is used to denote which physical hospital location the HL7 message is associated with. While this field is important to have on the SearchTable for ease of filtering, many messages come through each day for each facility. This means that it is inefficient to use this field as an index in the Message Viewer search. Counter to this would be a field like PID.18 (or Patient Account Number). The number of messages associated with each account number is very small, so using this field as an index greatly increases the speed of the search.

Adding the Unselective parameter to the appropriate items tells message search which ones to treat as indexes. This in essence modifies the SQL used to pull the messages. Below you will find the difference in queries, based on fields being used as index or not, and how you can use these queries to determine which fields should be Unselective.

Index vs NoIndex Queries

Unselective="false" (Indexed) SQL Query Plan

image

This query is looping over the SearchTable values and, for each row, cross-referencing the MessageHeader table. For a value that is unique and doesn’t have many messages associated with it (i.e. Patient Account Number), this is more efficient.

Unselective="true" (%NOINDEX) SQL Query Plan

image

This query is looping over the MessageHeader table and, for each row, cross-referencing the SearchTable values. For a value that has many results associated with it (i.e. FacilityID), this method is faster to return the results.

How to Identify Problem Fields

The best way I have found to identify which fields need to be marked as Unselective is with Show Query. Create a separate search using each field in Message Viewer (adding the SearchTable field via Add Criterion) then click Show Query to show you the actual SQL being used by Message Viewer to pull the messages based on the filters selected.

image

Our first example is using a field from the SearchTable that does not have the Unselected parameter added. Notice the EnsLib_HL7.SearchTable.PropId = 19 and EnsLib_HL7.SearchTable.PropValue = '2009036'. This indicates the SearchTable field added as a filter and what value is being checked. Keep in mind that the ProdId will be unique to each search table field and may change from environment to environment.

image

How to Add Show Query to Message Viewer

If you don’t have the Show Query button enabled in Message Viewer, you can set the following Global in your given namespace.

set ^Ens.Debug("UtilEnsMessages","sql")=1

Viewing the SQL Query Used by the Message Viewer

SQL - Unselective=“false”

SELECT TOP 100 
head.ID As ID, {fn RIGHT(%EXTERNAL(head.TimeCreated),999 )} As TimeCreated, 
head.SessionId As Session, head.Status As Status, 
CASE head.IsError 
WHEN 1 
THEN 'Error' ELSE 'OK' END As Error, head.SourceConfigName As Source, 
head.TargetConfigName As Target, head.SourceConfigName, head.TargetConfigName, 
head.MessageBodyClassName As BodyClassname, 
(SELECT LIST(PropValue) 
FROM EnsLib_HL7.SearchTable 
WHERE (head.MessageBodyId = DocId) And PropId=19) As SchTbl_FacilityID, 
EnsLib_HL7.SearchTable.PropId As SchTbl_PropId 
FROM Ens.MessageHeader head, EnsLib_HL7.SearchTable 
WHERE (((head.SourceConfigName = 'component_name' OR head.TargetConfigName = 'component_name')) 
AND head.MessageBodyClassName=(('EnsLib.HL7.Message')) 
AND (head.MessageBodyId = EnsLib_HL7.SearchTable.DocId) 
AND EnsLib_HL7.SearchTable.PropId = 19 AND EnsLib_HL7.SearchTable.PropValue = '2009036') 
ORDER BY head.ID Desc

Next, take that query into SQL and manually modify it to add %NOINDEX. This is what is telling the query to not treat this value as an index.

SQL - Unselective=”true” - %NOINDEX

SELECT TOP 100 
head.ID As ID, {fn RIGHT(%EXTERNAL(head.TimeCreated),999 )} As TimeCreated, 
head.SessionId As Session, head.Status As Status, 
CASE head.IsError 
WHEN 1 
THEN 'Error' ELSE 'OK' END As Error, head.SourceConfigName As Source, 
head.TargetConfigName As Target, head.SourceConfigName, head.TargetConfigName, 
head.MessageBodyClassName As BodyClassname, 
(SELECT LIST(PropValue) 
FROM EnsLib_HL7.SearchTable 
WHERE (head.MessageBodyId = DocId) And PropId=19) As SchTbl_FacilityID, 
EnsLib_HL7.SearchTable.PropId As SchTbl_PropId 
FROM Ens.MessageHeader head, EnsLib_HL7.SearchTable 
WHERE (((head.SourceConfigName = 'component_name' OR head.TargetConfigName = 'component_name')) 
AND head.MessageBodyClassName='EnsLib.HL7.Message' 
AND (head.MessageBodyId = EnsLib_HL7.SearchTable.DocId) 
AND EnsLib_HL7.SearchTable.PropId = 19 AND %NOINDEX EnsLib_HL7.SearchTable.PropValue = (('2009036'))) 
ORDER BY head.ID Desc

If there is a significant difference in the amount of time needed to return the first and second queries, then you have found a field that should be modified. In our case, we went from queries timing out after a few minutes to an almost instantaneous return.

Applying the Fix - Modifying Your Code

Once you have identified which fields need to be fixed, you can add the Unselective="true" to each affected Item in your custom SearchTable class. See the below example.

Custom SearchTable Class

/// Custom HL7 Search Table adds additional fields to index.
Class CustomClasses.SearchTable.CustomSearchTable Extends EnsLib.HL7.SearchTable
{

XData SearchSpec [ XMLNamespace = "http://www.intersystems.com/EnsSearchTable" ]
{
<Items>
		// Increase performance by setting Unselective="true" on fields that are not highly unique.
		// This essentially tells Message Search to not use an index on these fields.

		// facility ID in MSH.4
   		<Item DocType=""	PropName="FacilityID" Unselective="true">		[MSH:4]		</Item>
   		// Event Reason in EVN.4
   		<Item DocType=""	PropName="EventReason" Unselective="true">		[EVN:4]		</Item>
   		// Patient Account (Add PV1.19 to prebuilt PID.18 search)
   		<Item DocType=""	PropName="PatientAcct">		[PV1:19]	</Item>
   		// Document type
   		<Item DocType=""	PropName="DocumentType" Unselective="true">	[TXA:2]		</Item>
   		// Placer Order ID
   		<Item DocType=""	PropName="PlacerOrderID">	[OBR:2.1]	</Item>
   		// Filler Order ID
   		<Item DocType=""	PropName="FillerOrderID">	[OBR:3.1]	</Item>
   		// Universal Service ID
   		<Item DocType=""	PropName="ServiceID" Unselective="true">		[OBR:4.1]	</Item>
   		// Universal Service ID
   		<Item DocType=""	PropName="ProcedureName" Unselective="true">	[OBR:4.2]	</Item>		
   		// Diagnostic Service Section
   		<Item DocType=""	PropName="ServiceSectID" Unselective="true">	[OBR:24]	</Item>
   		// Appointment ID
   		<Item DocType=""	PropName="AppointmentID">	[SCH:2]		</Item>
   		// Provider Fields
   		<Item DocType=""	PropName="ProviderNameMFN">	[STF:3()]		</Item>
   		<Item DocType=""	PropName="ProviderIDsMFN">	[MFE:4().1]		</Item>
   		<Item DocType=""	PropName="ProviderIDsMFN">	[STF:1().1]		</Item>
   		<Item DocType=""	PropName="ProviderIDsMFN">	[PRA:6().1]		</Item>
	</Items>
}

Storage Default
{
<Type>%Storage.Persistent</Type>
}

}

Summary

Quick message searching is vital to day-to-day integration operations. By utilizing the Unselective property, it is now possible to maintain this functionality, despite an ever-growing database. With this quick and easy-to-implement change, you will be back on track to confidently providing service and troubleshooting issues in your Health Connect environment.

1
8 219
Article Jinyao · Feb 21, 2025 4m read

Motivation

I didn't know about ObjectScript until I started my new job. Objectscript isn't actually a young programming language. Compared to C++, Java and Python, the community isn't as active, but we're keen to make this place more vibrant, aren't we?

I've noticed that some of my colleagues are finding it tricky to get their heads around the class relationships in these huge projects. There aren't any easy-to-use modern class diagram tool for ObjectScript.

Related Work

I have tried relavant works:

10
4 473
Article Andrew Sklyarov · Nov 2, 2025 7m read

Over time, while I was working with Interoperability on the IRIS Data Platform, I developed rules for organizing a project code into packages and classes. That is what is called a Naming Convention, usually. In this topic, I want to organize and share these rules. I hope it can be helpful for somebody.

 

4
2 82
Announcement Larry Finlayson · Nov 3, 2025
    Using InterSystems Embedded Analytics – Virtual December 1-5, 2025

    Embed analytics capabilities in applications and create the supporting business intelligence cubes.
    This 5-day course teaches developers and business intelligence users how to embed real-time analytics capabilities in their applications using InterSystems IRIS® Business Intelligence.
    This course presents the basics of building data models from transactional data using the InterSystems IRIS BI Architect, exploring those models and building pivot tables and charts using the InterSystems IRIS BI Analyzer, as well as creating

0
0 21