Follow-up Relations

In this section, we explain how structured data for medications relations is represented in the NLP API JSON output and in the Output Database schema. We also provide sample queries to illustrate the key aspects of the data schema.

After reading this page, we hope you will:

  1. Understand what follow-up relations are.
  2. Know how to retrieve data for follow-up relations.

For an example of building on this data, see also the Simple Query App Tutorial, which walks through a simple web-based search application over the NLP output stored in this database.

The content in this section builds on the concepts and data models explained in earlier sections (see Entity-level Tables, and Document-level Tables).

What are Follow-up Relations?

Follow-up recommendations are commonly found in diagnostic reports such as Radiology, Pathology and Cardiology reports. For example, the NLP API will extract them from sentences in radiology reports where the dictating radiologist indicates that a follow-up study should be performed. The radiologist will typically provide some or all of the following information in a follow-up recommendation:

  • Reason: the pathology identified that should be followed up e.g. a lung nodule.
  • Procedure: the type of diagnostic procedure that should be performed for further evaluation.
  • Time expression: when the follow-up procedure should be performed.

The NLP API extracts these as arguments of a follow-up relation.

Consider this follow-up recommendation:

A follow-up Head CT scan in 3 months time is recommended to exclude malignancy

From the above sentence, the NLP API extracts the arguments comprising the follow-up relation as illustrated below:

Qualifier relation required and optional arguments

Note, at least one of the three types of arguments must be provided for a follow-up relation to be extracted.

JSON Data Model

Consider the following sentence:

A follow-up Head CT scan in 3 months time is recommended to exclude malignancy

The JSON output for the follow-up relation extracted from this sentence is shown below:

{
"relations": {
"followups": [
{
"label": "RFO0",
"attributes": {
"confidence": null,
"polarity": "asserted"
},
"args": {
"procedures": [
{
"ref": "E1",
"text": [
"Head CT scan"
]
}
],
"time_expression": {
"ref": "E2",
"text": [
"3 months"
]
},
"reasons": [
{
"ref": "E3",
"text": [
"malignancy"
]
}
]
},
"concept_links": []
}
]
}
}

Notice the following:

  1. The followups array is an element of the relations object. Each element of the followups array is a single object representing a follow-up relation.
  2. A follow-up relation instance has three types of named arguments: reasons, procedures and time_expression.
  3. The reasons argument is an array of entity references to the reasons for the follow-up recommendation. Note that multiple reasons may be associated with one follow-up relation.
  4. Likewise, the procedures argument is an array of references to entities about procedures related to the follow-up. Like reasons for follow-ups, multiple procedures may be found in one follow-up relation.
  5. The time_expression argument is a reference to an entity that indicates the timeline for the follow-up. Note that only one time_expression entity is extracted per follow-up relation.
  6. Follow-up relations have a polarity attribute. The value of the polarity can be negated or asserted. The negated follow-up relation is extracted when the radiologist explicitly indicates that no follow-up is necessary.

Follow-up Relation Tables

In the Output Database schema, the follow-up relations data model is implemented in the followuprelation table, and its related tables: followuprelationreason and followuprelationprocedure.

The following ER diagram shows the relationship between these tables:

Entity-Relation diagram showing followuprelation and its associated tables.

From the ER diagram above, observe that:

  1. The followuprelation table stores the polarity attribute, and the entity_id of the time_expression argument.

  2. The time_expression_id column of the followuprelation table is a foreign key reference to the entity table, or null. From the entity table you can perform a series of inner joins to access the entity information from entity-related tables, see Entity-level Tables.

  3. The followup_id columns of the followuprelationreason and the followuprelationprocedure tables contain foreign key references to the followuprelation table. Hence,

    1. to get the reason for a follow-up relation, perform an inner join on the primary key of the followuprelation and the followup_id of the followuprelationreason table.
    2. to get the procedure for a follow-up relation, perform an inner join on the primary key of the followuprelation and the followup_id of the followuprelationprocedure table.
  4. To retrieve information about the follow-up relation arguments such as the reason or procedure, you must perform an inner join on the corresponding entity_id keys with the entity associated entity-related tables, see Entity-level Tables.

It’s important to note the cardinality of the relations. A follow-up relation can be associated with:

  • one or more procedures entities
  • zero or more reasons entities
  • zero or one time_expression entity

When querying follow-up relations, it is important to note that unlike other relations, there are no independent or required arguments. The reasons, procedures or time_expression for follow-up relations may be null. This has particular significance when you are performing left joins on these tables.

Sample Queries

In this section, we present queries to illustrate how to write SQL queries to retrieve information about qualifier relations. The SQL queries will be discussed in order as follows:

Note: Because follow-up relations are specific to Radiology reports, please use an Output Database that contains output from processing Radiology reports.

Query: Display terms for arguments in follow-up relations

This query retrieves the annotated terms follow-up relation arguments. This query illustrates the cardinality of the relation between a follow-up relation and its arguments.

The query involves the following steps:

  1. Using a CTE, create a temporary named result set, reason_terms, which contains follow-up relation ID, and the annotated text for follow-up reasons. This involves the following:
    1. Joining the followuprelation table with the followuprelationreason table using followup_id foreign key reference. Then perform a series of inner joins with entity and foundentity tables. The annotated term is found in the foundentity table.
    2. Aggregating the annotated terms using a Window function to compute a comma-delimited list. At this point there will be duplicate rows for each followuprelation.id - one for each reason associated with a follow-up relation instance. Later, these duplicate rows will be removed in the GROUP BY clause in the enclosing query.
  2. As in step one, create a temporary named result set, procedure_terms which contains the follow-up relation ID, and the annotated text for follow-up procedures.
  3. Then, create a temporary named result set, time_expression which contains follow-up relation ID and the annotated text for the follow-up time expression.
  4. In the enclosing SQL query, use a subquery to create a named result set, ids, which contains the follow-up relation primary key ID. Then, perform a series of left joins on the ID field of the ids result set and the reason_terms, procedure_terms and time_expression result sets. The left join on the ids.followup_relation.id ensures that all follow-up relations are present in the final results, whether or not any individual argument is null.
WITH reason_terms AS (SELECT followuprelation.id AS followup_relation_id,
string_agg(reason_fe.text, ', ') OVER (PARTITION BY followuprelation.id) AS reason_terms
FROM followuprelation
-- retrieve reason entity for follow up
JOIN followuprelationreason reason
ON followuprelation.id = reason.followup_id
JOIN entity reason_e
ON reason_e.id = reason.entity_id AND reason_e.type_='found'
JOIN foundentity reason_fe
ON reason_fe.id = reason_e.entity_id),
time_expression_terms AS (SELECT followuprelation.id AS followup_relation_id, time_fe.text AS time_expression
FROM followuprelation
-- retrieve reason entity for follow up
JOIN entity time_e
ON time_e.id = followuprelation.time_expression_id
JOIN foundentity time_fe
ON time_fe.id = time_e.entity_id AND time_e.type_='found'),
procedure_terms AS (SELECT followuprelation.id AS followup_relation_id,
string_agg(procedure_fe.text, ', ')
OVER (PARTITION BY followuprelation.id) AS procedure_terms
FROM followuprelation
-- retrieve reason entity for follow up
JOIN followuprelationprocedure procedure
ON followuprelation.id = procedure.followup_id
JOIN entity procedure_e
ON procedure_e.id = procedure.entity_id AND procedure_e.type_='found'
JOIN foundentity procedure_fe
ON procedure_fe.id = procedure_e.entity_id)
SELECT fr.id, reason_terms.reason_terms, procedure_terms.procedure_terms,
time_expression_terms.time_expression
FROM followuprelation fr
LEFT JOIN reason_terms -- IMPORTANT: left joins required
ON reason_terms.followup_relation_id = fr.id
LEFT JOIN procedure_terms
ON procedure_terms.followup_relation_id = fr.id
LEFT JOIN time_expression_terms
ON time_expression_terms.followup_relation_id = fr.id
GROUP BY fr.id, reason_terms.reason_terms, procedure_terms.procedure_terms,
time_expression_terms.time_expression
LIMIT 6 OFFSET 12;
idreason_termsprocedure_termstime_expression
13obstructionfollow-up CT, scan
14discharge
15blood cultures
16platelets03/16/22
17Further evaluationMRI
18further evaluationCT, MRI

Query: Frequency of reasons for follow-up recommendations

This query is useful as a preliminary exploration of the reasons given for follow-ups. Instead of analyzing the annotated terms which have many linguistic variants, we analyze the reasons using standardized concepts and their semantic type classification.

Because we are interested in the reasons for follow-ups, we start by querying the followuprelationreason table. Then, we can retrieve the concepts and entity type for every follow-up reason entity by performing an inner join with the entity table, and related tables such as foundentityconcept and foundentitytype tables. Note that NLP API supports multiple ontologies for concept and semantic type classification purposes. In this query, we use the UMLS metathesaurus for semantic type classification, and SNOMED CT for concept classification of the annotated terms.

SELECT reason_c.description AS reason_concept,
reason_c.ontology AS concept_ontology, reason_fet.type_name AS reason_semantic_type, reason_fet.ontology AS reason_semantic_type_ontology,
count(*) AS count
FROM followuprelationreason
JOIN entity reason_e
ON reason_e.id = followuprelationreason.entity_id AND reason_e.type_='found'
JOIN foundentity reason_fe
ON reason_fe.id = reason_e.entity_id
JOIN foundentitytype reason_fet
ON reason_fet.found_entity_id = reason_fe.id AND reason_fet.ontology = 'umls' -- Select ontology e.g. 'snomed'
JOIN foundentityconcept reason_fec
ON reason_fec.found_entity_id = reason_fe.id
JOIN concept reason_c
ON reason_c.concept_id = reason_fec.concept_id
AND reason_c.ontology = reason_fec.concept_ontology -- Required
WHERE reason_c.ontology = 'snomed' -- Select an ontology e.g. 'snomed', 'medcin', 'radlex', 'umls_nci', 'umls_loinc'
GROUP BY reason_fe.text, reason_c.description, reason_c.ontology, reason_fet.type_name, reason_fet.ontology
ORDER BY 1
LIMIT 5;
reason_conceptconcept_ontologyreason_semantic_typereason_semantic_type_ontologycount
Appointment date (finding)snomedFindingumls2
Atrial fibrillation (disorder)snomedDisease or Syndromeumls1
Barrett’s esophagus (disorder)snomedDisease or Syndromeumls1
Cardiac enzyme above reference range (finding)snomedFindingumls1
Enchondroma of bone (disorder)snomedNeoplastic Processumls1

Query: Frequency of follow-up imaging recommendations

This query retrieves the count of follow-up recommendations by imaging modality. Because this query is about the procedure associated with follow-up relations, we start with the followuprelationprocedure table. By performing a series of inner joins with entity-related tables, we get the concept and entity type for procedure entities from the concept and foundentitytype tables respectively. Note, for this query, we used the RadLex ontology as a concept and semantic type classification system; And, we constrain the resultset to only those follow-ups where the procedure is of semantic type imaging modality.

SELECT proc_c.description AS procedure_concept, proc_c.ontology AS concept_ontology,
proc_fet.type_name AS procedure_semantic_type, proc_fet.ontology AS procedure_semantic_type_ontology,
count(*) AS count
FROM followuprelationprocedure
JOIN entity proc_e
ON proc_e.id = followuprelationprocedure.entity_id AND proc_e.type_='found'
JOIN foundentity proc_fe
ON proc_fe.id = proc_e.entity_id
JOIN foundentitytype proc_fet
ON proc_fet.found_entity_id = proc_fe.id AND proc_fet.ontology = 'radlex' -- Ontology for semantic classification e.g. 'umls', 'snomed'
JOIN foundentityconcept proc_fec
ON proc_fec.found_entity_id = proc_fe.id
JOIN concept proc_c
ON proc_c.concept_id = proc_fec.concept_id AND proc_c.ontology = proc_fec.concept_ontology
WHERE proc_c.ontology = 'radlex' -- Ontology for concept classification e.g. 'snomed', 'medcin'
AND proc_fet.type_name = 'imaging modality' -- Select only procedures with RadLex semantic type of 'imaging modality'
GROUP BY proc_c.description, proc_c.ontology, proc_fet.type_name, proc_fet.ontology
ORDER BY count DESC
LIMIT 5;
procedure_conceptconcept_ontologyprocedure_semantic_typeprocedure_semantic_type_ontologycount
magnetic resonance imaging (imaging modality)radleximaging modalityradlex4
computed tomography (imaging modality)radleximaging modalityradlex1
projection radiography (imaging modality)radleximaging modalityradlex1