Smile CDR MDM works for most HAPI FHIR resources, independently for each resource type. In the MDM documentation, we use "Patient" to illustrate MDM use cases.
Smile’s Master Data Management solution allows healthcare organizations to maintain links between source records and its real-life representation known as the Golden Record. The Golden Record id plays the role of a unique identifier for that resource across all of the different source systems. For example, if the FHIR repository consolidates lab data, medication data, claims data etc from disparate systems that all maintain their own Patient records, all of those records will be tied together as belonging to the same Patient.
Additional details about Smile CDR MDM can be found in the HAPI FHIR MDM documentation and cover the following topics:
If you'd like to jump right in and start trying things out, a quick walkthrough is available in our Smile CDR MDM Quickstart Guide. Otherwise, if you'd like to understand in detail how MDM is configured within Smile CDR read on.
To enable MDM on a Smile CDR FHIR repository, several modules are used together. The following diagram shows how these different modules relate to each other.
This diagram shows the following modules:
The Cluster Manager Module contains the configuration used to connect to the selected message broker.
See Message Broker for information on how to select and configure a message broker. By default an embedded Apache ActiveMQ server will be used, and this is acceptable for testing purposes but an external broker should be used in a production scenario.
MDM uses a Subscription Module and the configured message broker to process incoming resources asynchronously.
MDM uses the FHIR Storage Module specified by the Subscription Matching Module it depends on. MDM support is configured on the FHIR Storage module via the mdm.enabled and subscription.message.enabled properties, requiring both to be enabled.
A Subscription Matching module should be created with a module dependency on the chosen FHIR Storage module. When MDM starts up, it will create a subscription for each MDM type. These subscriptions have a "message" channel type and submit the incoming MDM resources on the "mdm" channel.
The MDM Module subscribes to the "mdm" channel and processes the incoming MDM resources, creating MDM links according to the rules configured in this module. See HAPI FHIR MDM and MDM Rule Definiton for details on how the MDM rules are configured.
The Message Broker configured in the Cluster Manager Module might be used extensively by the MDM module, specially if operations like $mdm-submit
are used. Many FHIR resources could potentially be pushed to the "mdm" channel of the message broker, so a reliable external broker is recommended for this reason.
Users of MDM often want to query across all the resources associated with all linked patients in a single query. This is called MDM Search Expansion. For example, a user may want to know all the Observations of a given Patient, but also include all the observations of all matched patients. The following query shows an example of the usage of the :mdm
parameter modifier to expand a search across all linked patients.
GET [base]/Observation?patient:mdm=Patient/123
The above query will return all Observations for Patient/123 and all Observations for all linked patients.
MDM Expansion is also supported on the $everything
operation via the _mdm
query parameter. Below is an example:
GET [base]/Patient/123/$everything?_mdm=true
In order to support expanded reference searches using the :mdm
search parameter qualifier, you must enable the mdm.search_expansion.enabled property.
If expanded reference searches are enabled and the user has the FHIR_AUTO_MDM permission, search parameters in the FHIR Patient Compartment will be expanded even when the :mdm
qualifier is not explicitly provided.
This will also automatically convert any $everything
operation invocations to use mdm expansion.
The MDM Troubleshooting Log can be helpful in diagnosing issues relating to MDM processing.
See MDM UI for more information about this feature.
Smile MDM is designed to be flexible to work on different kinds of enterprise environments. Below are some example MDM scenarios.
Some enterprises have a strict intake process that identifies all patients with a uniquely assigned Enterprise Identifier (EID) and all interactions identify that Patient via their EID.
Smile MDM has EID management configuration options to support this scenario. By default, the MDM system does not allow updates to an EID. This can be disabled via property. There is a similar property which controls the ability for a resource to hold multiple EIDs simultaneously; this is disabled by default.
See Using Enterprise Identifiers in MDM Rule Definition section for more details about using EIDs and how these options change the way the incoming resources are processed by the MDM Module.
Other enterprises, however, need to consolidate records from different systems where it is not known beforehand which records refer to the golden record. To support this scenario, Smile MDM provides a rich set of MDM Matching Rules to algorithmically detect when two Patient records refer to the same person.
Based on the rule configuration, some patients will be identified as exact matches and automatically linked.
Others may be flagged as possible matches or may identify that two Golden Records in the system may be duplicates.
Smile CDR provides an MDM User Interface to manually resolve these possible matches and duplicates.
The MDM Rule Definiton section provides details on how to create MDM rules for resource matching.
See Sample MDM Rules below for an example of a rules file.
MDM can be configured to block certain resources from MDM matching entirely using a set of json rules.
For more information on block list rules, see the hapi fhir customizations section
Additional examples can be found here.
Smile MDM can also be used to support business analytics, automatically linking batch data from different systems. In this scenario, the FHIR repository might be reset before each load, or it may link to external records maintained in a data warehouse.
{
"version": "1",
"mdmTypes": ["Patient", "Practitioner"],
"candidateSearchParams": [
{
"resourceType": "Patient",
"searchParams": [
"birthdate"
]
},
{
"resourceType": "*",
"searchParams": [
"identifier"
]
}
],
"candidateFilterSearchParams": [
{
"resourceType": "*",
"searchParam": "active",
"fixedValue": "true"
}
],
"matchFields": [
{
"name": "family-name-double-metaphone",
"resourceType": "*",
"resourcePath": "name.family",
"matcher": {
"algorithm": "DOUBLE_METAPHONE"
}
},
{
"name": "given-name-double-metaphone",
"resourceType": "*",
"resourcePath": "name.given",
"matcher": {
"algorithm": "DOUBLE_METAPHONE"
}
},
{
"name": "given-name",
"resourceType": "*",
"resourcePath": "name.given",
"similarity": {
"algorithm": "LEVENSCHTEIN",
"matchThreshold": 0.8
}
},
{
"name": "family-name",
"resourceType": "*",
"resourcePath": "name.family",
"similarity": {
"algorithm": "LEVENSCHTEIN",
"matchThreshold": 0.8
}
},
{
"name": "birthdate",
"resourceType": "*",
"resourcePath": "birthDate",
"matcher": {
"algorithm": "DATE"
}
},
{
"name": "gender",
"resourceType": "*",
"resourcePath": "gender",
"matcher": {
"algorithm": "STRING",
"exact": true
}
},
{
"name": "family-name-soundex",
"resourceType": "*",
"resourcePath": "name.family",
"matcher": {
"algorithm": "SOUNDEX"
}
},
{
"name": "given-name-soundex",
"resourceType": "*",
"resourcePath": "name.given",
"matcher": {
"algorithm": "SOUNDEX"
}
},
{
"name": "city",
"resourceType": "*",
"resourcePath": "address.city",
"similarity": {
"algorithm": "LEVENSCHTEIN",
"matchThreshold": 0.8
}
},
{
"name": "address-line",
"resourceType": "*",
"resourcePath": "address.line",
"similarity": {
"algorithm": "LEVENSCHTEIN",
"matchThreshold": 0.8
}
},
{
"name": "state",
"resourceType": "*",
"resourcePath": "address.state",
"similarity": {
"algorithm": "LEVENSCHTEIN",
"matchThreshold": 0.8
}
},
{
"name": "postal-code",
"resourceType": "*",
"resourcePath": "address.postalCode",
"similarity": {
"algorithm": "LEVENSCHTEIN",
"matchThreshold": 0.8
}
},
{
"name": "family-name-caverphone2",
"resourceType": "*",
"resourcePath": "name.family",
"matcher": {
"algorithm": "CAVERPHONE1"
}
},
{
"name": "family-name-caverphone1",
"resourceType": "*",
"resourcePath": "name.family",
"matcher": {
"algorithm": "CAVERPHONE2"
}
},
{
"name": "name-prefix",
"resourceType": "*",
"resourcePath": "name.prefix",
"matcher": {
"algorithm": "STRING"
}
},
{
"name": "family-name-normalize-substring",
"resourceType": "*",
"resourcePath": "name.family",
"matcher": {
"algorithm": "SUBSTRING"
}
},
{
"name": "given-name-normalize-substring",
"resourceType": "*",
"resourcePath": "name.given",
"matcher": {
"algorithm": "SUBSTRING"
}
}
],
"matchResultMap": {
"given-name-double-metaphone,family-name,birthdate,gender,address-line,city,state,postal-code": "MATCH",
"given-name-double-metaphone,family-name,birthdate,gender": "POSSIBLE_MATCH"
},
"eidSystems": {
"*": "http://hl7.org/fhir/sid/us-ssn"
}
}
By default, MDM runs on a single thread in a background. If your MDM rules are defined by an EID, and your message broker is Kafka, you are afforded the opportunity to run MDM on multiple threads. In order to enable multiple consumers for MDM, you have to perform the following steps:
mdm
kafka topic to the amount of threads you want doing MDM processing.On boot, each consumer will consume from a single partition. Note that this only works if you define:
eidSystem
or eidSystems
in your MDM rules, in which case the value of the eidSystem
becomes the partition key. If multiple eidSystems
are defined, the value of the first eidSystem
becomes the partition key orMDM Partition Key Script
is defined as per option 3. above, in which case the script must provide the partition key for each resource.To fully remove MDM functionality from the system, first turn off the MDM module. You will then also need to manually set the status of all subscriptions to "Off". Additionally, if you no longer plan on using MDM, you can run the $mdm-clear operation first to delete all Golden Resources and MDM-Links from the system as well.