Advanced FHIR search features

This page explains how to search for FHIR resources using more advanced query functionality available through the projects.locations.datasets.fhirStores.fhir.search method. This guide assumes that you are already familiar with the contents of Searching for FHIR resources.

String search modifiers

A string search defaults to a prefix match that is case and accent insensitive through folding to the standard Unicode NFC form. Punctuation and extra whitespace is ignored.

The following modifiers are available:

  • :contains matches resources with the specified value anywhere in the string, for example name:contains=eve matches Evelyn and Severine.
  • :exact matches the entire string including case and accents, for example name:exact=Eve doesn't match eve or Evelyn.

Comparators and precision for numbers, dates, and quantities

Values used in a numeric or date search depend on the precision of the parameter value. For example, the number 7.00 has an implicit range of 6.995 inclusive to 7.005 exclusive. The date 2015-08-12 has a range of 2015-08-12T00:00:00 inclusive to 2015-08-13T00:00:00 exclusive.

Precision affects what results are returned for equality comparisons. For example, a value of 7.03 in a resource would match a search for value=7.0 but would not match a search for value=7.00.

All clinically significant floating point values in FHIR are represented by types such as Decimal and Quantity that record the precision of the stored value. As an exception there are a few fields that use simple integers, for example to represent a position in a sequence, and searches on those fields are exact numerical matches.

The following prefixes apply to numeric comparisons against a singleton value. If no prefixes are specified, the default is eq.

  • eq: equals, the exact stored value is inside the range defined by the precision of the parameter value
  • ne: not equals, the opposite of eq
  • gt: the exact stored value is greater than the exact parameter value
  • lt: the exact stored value is less than the exact parameter value
  • ge: the exact stored value is greater than or equal to the exact parameter value
  • le: the exact stored value is less than or equal to the exact parameter value

Date values have an implicit range based on the level of specificity of the value (one year, one month, one day). Other data types such as Range and Period contain explicit upper and lower bounds. The following prefixes apply to range comparisons. If no prefixes are specified, the default is eq.

  • eq: equals, the range of the parameter value fully contains the range of the target
  • ne: not equals, the opposite of eq
  • gt: greater than, the range above the parameter value overlaps with the range of the target
  • lt: less than, the range below the parameter value overlaps with the range of the target
  • ge: greater than or equal to
  • le: less than or equal to
  • sa: the range of the parameter value starts after the target range
  • eb: the range of the parameter value ends before the target range

Token search parameters apply to cases where a value is not an arbitrary string, but rather an entity in a naming system. String matching on a token parameter is exact.

Most token searches apply to complex data types that contain a system that is a URI indicating the naming system that the code value is taken from. These searches support the following value syntaxes:

  • [parameter]=[code] matches the code value regardless of the system
  • [parameter]=[system]|[code] must match both the system and code specified
  • [parameter]=|[code] matches code when the system value is empty
  • [parameter]=[system]| matches any code with the given system value

There are several modifiers that trigger alternate token search functionality:

  • :not negates the matching conditions of a token search
  • :text does a string search (not exact match) on the text or display field associated with the code, instead of the code value itself
  • :above takes a parameter only of the form [system]|[code] and matches resources where the code in the resource subsumes the query parameter. To use this modifier the specified system must exist in the FHIR store as a CodeSystem resource.
  • :below is like :above but matches if the code in the resource is subsumed by the query parameter.
  • :in takes a single parameter using the reference parameter syntax, for example code:in=ValueSet/1234. The reference must refer to a ValueSet resource within the same FHIR store. The modifier matches any code that is in the referenced ValueSet.
  • :not-in negates the conditions of :in

Token searches also apply to boolean and URI fields and certain string fields where only exact match is allowed. In these cases, the only parameter format is [parameter]=[value].

Searching for missing values

The search modifier :missing can be used on any search parameter to match based on the presence or absence of any value in the specified field. For example, Patient?gender=unknown matches resources that explicitly contain the unknown enum value for gender, but as this field is not required there may be other resources that do not populate the field at all. Such resources can be matched by Patient?gender:missing=true. The converse, Patient?gender:missing=false matches any resource that explicitly populates this field.

The special search parameter _content performs a text match on all fields that are the target of any search parameter in any resource. By default it matches resources that contain all of the words in the query, with support for additional operators:

  • | is the OR operator, for example abc | def | ghi xyz will match a resource that contains xyz and one or more of abc def ghi.
  • - is the NOT operator, for example abc -def will match a resource that contains abc but does not contain def.

The parameter _text performs the same type of match only on the Narrative field that is intended to contain a human-readable summary of the resource contents. The Cloud Healthcare API does not automatically generate this summary but supports the _text search parameter if this data was populated by the client when creating or updating the resource.

Composite search parameters

When searching using multiple query parameters, there are cases where individual search parameters combined with AND would match unintended results. Composite search parameters are a special type of search parameter that address this issue.

For example, the Observation resource may contain multiple values in the component field, each of which contains a pair of code and value. A search for Observation?component-code=8867-4&component-value-quantity=lt50 would match a resource that had one component containing a code of 8867-4 and a different component containing a value less than 50. This search cannot be used to restrict to a match of these two values within the same component.

Composite search parameters define a new parameter that combines two other search parameters and defines a level of nesting within which they must both match. In the query, the two values are joined by $. For example, Observation has a composite parameter component-code-value-quantity that can restrict the previous example to a single component by searching for Observation?component-code-value-quantity=8867-4$lt50. These parameters are defined by the FHIR specification and do not exist for all combinations of search parameters.

Composite search parameters do not allow modifiers.

As with all search parameters, information on which composite parameters are supported by the Cloud Healthcare API can be found in the capability statement or FHIR Conformance Statement.

A chained search allows a search to traverse references within the context of a query. The basic syntax for a chained search is:

[reference parameter]:[resource type].[inner search parameter]=[inner value]

If the reference parameter only refers to one resource type, the :[resource type] may be omitted, resulting in:

[reference parameter].[inner search parameter]=[inner value]

For example, Observation has a reference search parameter subject that may point to a Group, Device, Patient, or Location. To find Observations that have a subject which is a Patient having a name beginning with "Joe", you can search Observation?subject:Patient.name=Joe.

Chained searches may have more than one level, for example Observation?subject:Patient.organization:Organization.name=Acme. In this example, :Organization could be omitted because the organization search parameter can only point to Organization resources, resulting in Observation?subject:Patient.organization.name=Acme.

If the query has multiple chained parameters, each chain is evaluated separately. For example, Patient?general-practitioner.name=Joe&general-practitioner.address-country=Canada would match a Patient that had two general-practitioner references, one named "Joe" and the other having an address in Canada. There is no syntax to group these clauses together to match only Joe from Canada.

A reverse chained search matches resources based on criteria on other resources that refer to them. The syntax for a reverse chained search is:

_has:[resource type]:[reference parameter]:[search parameter]=[value]

For example, the Appointment resource has a search parameter patient referring to a Patient resource. To find all Patient resources that are referenced by an Appointment resource with a date of 2020-04-01, use Patient?_has:Appointment:patient:date=eq2020-04-01.

Reverse chains can be recursive, for example Practitioner?_has:Encounter:practitioner:_has:Claim:encounter:created=eq2020-04-01 would match a Practitioner P if there is an Encounter E and a Claim C such that C has a created date of 2020-04-01, C refers to E through its encounter reference, and E refers to P through its practitioner reference.

Including additional resources in search results

The _include and _revinclude parameters request that the search results include additional resources ("included resources") related to the resources directly matching the query ("primary results"). Using these parameters is more efficient than making a series of requests to retrieve these additional resources separately. In the searchset bundle returned from the search, resources added by these parameters will be flagged with entry.search.mode = include to distinguish them from primary results which will have entry.search.mode = match.

Forward inclusion with _include adds resources referenced by the primary results, and reverse inclusion with _revinclude adds resources that reference the primary results. The reference to follow is specified by the name of a search parameter, and only reference fields that are available as search parameters can be used in this way.

The parameter formats to _include and _revinclude are the same, taking two or three values delimited by :. The first value is the resource type that the reference is coming from, the second value is the search parameter name, and the optional third value limits the resource type to a single type in cases where the reference can point to more than one type.

For example:

  • MedicationRequest?_include=MedicationRequest:subject searches over MedicationRequest resources, and for each resource returned also returns the target of the subject reference which might be a Group or Patient as defined in the FHIR specification.
  • MedicationRequest?_include=MedicationRequest:subject:Patient is similar but only returns subject references to Patient resources.
  • MedicationRequest?_revinclude=Provenance:target searches over MedicationRequest resources, and for each resource returned also returns any Provenance resources where the target reference on Provenance refers to the matching resource.

The modifier :iterate causes an _include or _revinclude to be evaluated iteratively. This modifier can follow an extra layer of references from included results, or follow recursive structures such as Observation:derived-from referring to another Observation. The depth of recursion is limited.

For example:

  • Observation?_include:iterate=Observation:derived-from:Observation searches over Observation resources and recursively follows the derived-from reference from matching Observation resources, and then from included resources, and so on.
  • MedicationRequest?_revinclude=Provenance:target&_include:iterate=Provenance:agent will search over MedicationRequest, include Provenance resources with a target that is in this result set, and then also include resources referenced through the agent parameter of those Provenance resources.

Included resources will be deduplicated so only one copy of a resource will be returned within a page of results even if it is found through multiple references. The same included resource will be returned on each page of results where a primary result relates to it.

Limiting fields returned in search results

The _elements parameter allows the client to request that only a subset of fields is returned for each search result to reduce the size of the response by omitting unnecessary data. The parameter accepts a comma-separated list of base element names in the resource, for example Patient?_elements=identifier,contact,link. Only these fields and their children will be included in the returned resources. Resources in the response that have been altered by this parameter will contain a meta.tag value of SUBSETTED to indicate that they are incomplete.

The Cloud Healthcare API has limited support for the _summary parameter, which provides pre-defined subsets of resource fields similar to _elements:

  • _summary=text returns only the text, id, and meta top-level fields
  • _summary=data removes the text field and returns all other fields