DSTU2 QA Preview

This page is part of the FHIR Specification (v1.0.0: DSTU 2 Ballot 3). The current version which supercedes this version is 5.0.0. For a full list of available versions, see the Directory of published versions . Page versions: R5 R4B R4 R3 R2

2.1.1 Search

FHIR Infrastructure Work GroupMaturity Level: N/ABallot Status: DSTU 2

One aspect that is fundamental to the way FHIR works is to search a set of resources. Search operations search through an existing set of resources by a set of search criteria supplied as parameters to the search. This page documents the FHIR search framework, starting with the simple cases, and working through to the full complexity. Implementations need only implement the amount of complexity that they require.

2.1.1.1 Summary Table

Search Parameter TypesParameters for all resourcesSearch result parameters
Number
Date/DateTime
String
Token
Reference
Composite
Quantity
URI
_id
_lastUpdated
_tag
_profile
_security
_text
_content
_list
_query
_sort
_count
_include
_revinclude
_summary
_elements
_contained
_containedType

In addition, there is a special search parameter _filter that allows a different method of searching.

2.1.1.2 Introduction

In the simplest case, a search is executed by performing a GET operation in the RESTful framework:

 GET [base]/[resourcetype]?name=value&...

For this RESTful search (see definition in RESTful API), the parameters are a series of name=[value] pairs encoded in the URL or as an application/x-www-form-urlencoded submission for a POST:

 POST  [base]/[type]/_search{?[parameters]{&_format=[mime-type]}}

The server determines which of the set of resources it serves meet the specific criteria, and returns the results in the HTTP response as a bundle which includes the resources that are the results of the search.

Search operations are executed in one of 3 defined contexts that control which set of resources are being searched:

  • A specified resource type: GET [base]/[ResourceType]?parameter(s)
  • A specified compartment, perhaps with a specified resource type in that compartment: GET [base]/Patient/[id]/[ResourceType]?parameter(s)
  • All resource types: GET [base]/_search?parameter(s) (parameters common to all types only)

Search operations can also be implemented in the messaging framework.

The server determination of which resources meet the criteria contained in the search parameters as described below. However the server has the prerogative to return additional search results if it believes them to be relevant. Note, though, that there is a special search for the most relevant context in which the search set is indeterminate: Patient MPI Search.

Search using GET may include sensitive information in the search parameters therefore secure communications and endpoint management are recommended, see Security Communications

2.1.1.3 Handling Errors

If a server is unable to execute a search request, it may return an error. A HTTP status code of 403 signifies that the server refused to perform the search, while some other 4xx or 5xx code signifies that some error occurred. When the search fails, a server SHOULD return an OperationOutcome detailing the cause of the failure. Note that an empty search result is not a failure.

In some cases, some of the parameters may have problems. For instance:

  • A parameter may refer to a non-existent resource e.g. GET [base]/Observation?subject=101, where 101 does not exist
  • A parameter may refer to an unknown code e.g. GET [base]/Observation?code=loinc|1234-1, where the LOINC code 1234-1 is not known to the server
  • A parameter may refer to a time that is out of scope e.g. GET [base]/Condition?onset=le1995, where the system only has data going back to 2001
  • A parameter may use an illegal or unaaceptable modifier e.g. GET [base]/Condition?onset:text=1995, where the modifier cannot be processed by the server
  • A data time parameter may have incorrect format e.g. GET [base]/Condition?onset=23%20May%202009

Where the content of the parameter is syntactically correct, servers SHOULD return an error. However where the issue is a logical condition (e.g. unknown subject or code), the server SHOULD process the search, including processing the parameter - with the effect of returning an empty search set, since the parameter cannot be satisfied.

In such cases, the search process MAY include an OperationOutcome in the search set that contains additional hints and warnings about the search process. This is included in the search results as an entry with search mode = outcome. Clients can use this information to improve future searches.

2.1.1.4 Standard Parameters

2.1.1.4.1 Parameters for all resources

These parameters are defined that apply to all resources: _content, _id, _lastUpdated, _profile, _query, _security, _tag, _text. In addition, the search parameter _text and _filter, (documented below) also applies to all resources (as do the search result parameters).

The search parameter _id refers to the logical id of the resource, and can be used when the search context specifies a resource type:

 GET [base]/Patient?_id=23

This search finds the patient resource with the given id (there can only be one resource for a given id). Functionally, this is equivalent to a simple read operation:

 GET [base]/Patient/23

however the search with parameter _id returns a bundle with the requested resource, instead of just the resource itself. Additional parameters can be added which may provide additional functionality on top of this base read equivalence (e.g. _include).

The search parameter _lastUpdated can be used to select resources based on the last time they were changed:

 GET [base]/Observation?_lastUpdated=>2010-10-01

This search finds any observations changed since 1-Oct 2010. When this search parameter is used, applications should consider synchronization approaches (RESTful history or the Subscription resource).

The search parameters _tag, _profile and _security parameters search on the equivalent elements in the meta element. For example

 GET [base]/Condition?_tag=http://acme.org/codes|needs-review

searches for all Condition resources with the tag:

{
  "system" : "http://acme.org/codes",
  "code" : "needs-review"
}

In the same manner:

 GET [base]/DiagnosticReport?_profile=http://hl7.org/fhir/StructureDefinition/lipid
 GET [base]/DiagnosticReport?_profile=Profile/lipid

restricts the search to only DiagnosticReport resources that are tagged that they conform to a particular profile. The second reference is relative, and refers a local profile on the same server.

_tag, _profile and _security parameters are all token types (see below).

2.1.1.4.2 Parameters for each resource

In addition to the _id parameter which exists for all resources, each FHIR resource type defines its own set of search parameters with their names, types, and meanings. These search parameters are on the same page as the resource definitions, and are also published as part of the standard conformance statement (XML or JSON).

Mostly, the defined search parameters correspond to a single element in the resource, but this is not required, and some search parameters refer to the same type of element in multiple places, or refer to derived values.

Some of the search parameters defined by the resources are associated with more than one path in the resource. This means that the search parameter matches if any of the paths contain matching content, and which ever path matches, the whole resource is returned in the search results. The client may have to examine the resource to determine which path contains the match.

Servers are not required to implement any of these search parameters (except for the _id parameter described above), and may define their own additional parameters if they wish.

2.1.1.4.3 Search Parameter Types

Each search parameter is defined with a type that defines how the search parameter behaves. These are the defined parameter types:

numberSearch parameter SHALL be a number (a whole number, or a decimal)
dateSearch parameter is on a date/time. The date format is the standard XML format, though other formats may be supported
stringSearch parameter is a simple string, like a name part. Search is case-insensitive and accent-insensitive. May match just the start of a string. String parameters may contain spaces
tokenSearch parameter on a coded element or identifier. May be used to search through the text, displayname, code and code/codesystem (for codes) and label, system and key (for identifier). Its value is either a string or a pair of namespace and value, separated by a "|", depending on the modifier used
referenceA reference to another resource
compositeA composite search parameter that combines a search on two values together
quantityA search parameter that searches on a quantity
uriA search parameter that searches on a URI (RFC 3986)

The search parameters can also have "modifiers" appended to them that control their behavior. The kinds of modifiers that can be used depend on the type of parameter.

2.1.1.4.4 Modifiers

Parameters are defined per resource, and their names may additionally specify a modifier as a suffix, separated from the parameter name by a colon. Modifiers are:

  • For all parameters (except combination): :missing. E.g. gender:missing=true (or false). Searching for "gender:missing=true" will return all the resources that don't have any value for the gender parameter (which usually equates to not having the relevant element in the resource). Searching for "gender:missing=false" will return all the resources that have a value for the "gender" parameter.
  • For string: :exact (the match needs to be exact, no partial matches, case sensitive and accent-sensitive), or :contains (case insensitive and accent-insensitive, partial match at start or end), instead of the default behavior (case insensitive and accent-insensitive, partial matches at the end of the string)
  • For token: :text (the match does a partial searches on the text portion of a CodeableConcept or the display portion of a Coding), instead of the default search which uses codes. Other defined modifiers are :in, :below, :above and :not-in which are described below
  • For reference: :[type] where [type] is the name of a type of resource
  • For uri: :below, :above indicate that instead of an exact match, either the search term left matches the value, or vice-versa

Server SHALL reject any search request that contains is suffixed by a modifier that the server does not support for that parameter. For example, if the server supports the "name" search param, but not the ":exact" modifier on the name, it should reject a search with the parameter "name:exact=Bill", using an HTTP 400 error with an OperationOutcome with a clear error message.

2.1.1.4.5 Prefixes

For the ordered parameter types number, date, and quantity, a prefix to the parameter value may be used to control the nature of the matching. To avoid URL escaping and visual confusion, the following prefixes are used:

eq the value for the parameter in the resource is equal to the provided value the range of the search value fully contains the range of the target value
ne the value for the parameter in the resource is not equal to the provided value the range of the search value does not fully contain the range of the target value
gt the value for the parameter in the resource is greater than the provided value the range above the search value intersects (i.e. overlaps) with the range of the target value
lt the value for the parameter in the resource is less than the provided value the range below the search value intersects (i.e. overlaps) with the range of the target value
ge the value for the parameter in the resource is greater or equal to the provided value the range above the search value intersects (i.e. overlaps) with the range of the target value, or the range of the search value fully contains the range of the target value
le the value for the parameter in the resource is less or equal to the provided value the range below the search value intersects (i.e. overlaps) with the range of the target value or the range of the search value fully contains the range of the target value
sa the value for the parameter in the resource starts after the provided value the range of the search value does overlap with the range of the target value, and the range below the search value contains the range of the target value
eb the value for the parameter in the resource ends before the provided value the range of the search value does overlap with the range of the target value, and the range above the search value contains the range of the target value
ap the value for the parameter in the resource is approximately the same to the provided value.
Note that the recommended value for the approximation is 10% of the stated value (or for a date, 10% of the gap between now and the date), but systems may choose other values where appropriate
the range of the search value overlaps with the range of the target value

If no prefix is present, the prefix 'eq' is assumed. Note that the way search parameters operate is not the same as the way the operations on two numbers work in a mathematical sense. sa ('starts-after') and eb ('ends-before') are not used with integer values.

For each prefix above, two interpretations are provided - the simple intent of the prefix, and the interpretation of the parameter when applied to ranges. The range interpretation is provided because for decimals and dates, the searches are always performed on values that are implicitly or explicitly a range. For instance, the number 2.0 has an implicit range of 1.95 to 2.05, and the date 2015-08-12 has an implicit range of the all the time during that day. If the target value is a Range, a Period, or a Timing, then the target is explicitly a range. Three ranges are identified:

range of the value The limits implied by the precision of the value The number 2.0 has a range of 1.95 to 2.05
The date 2015-08-12 has a range from 00:00 to 00:00 exclusive
range below the value Up to the specified value The range below 2.0 includes any value less or equal to <2.00000000000000000000
The range before 2015-08-12T05:23:45 includes any time up to 2015-08-12T05:23:45.000000000000000
range above the value The specified value and up The range above 2.0 includes any value greater or equal to <2.00000000000000000000
The range after 2015-08-12T05:23:45 includes any time up to 2015-08-12T05:23:45.000000000000000

The proper use of these is discussed further below.

2.1.1.4.6 number

Sarching on a simple numerical value in a resource. Examples:

[parameter]=100Values that equal 100, to 3 significant figures precision, so range [99.5 ... 100.5)
[parameter]=100.00Values that equal 100, to 5 significant figures precision, so range [99.995 ... 100.005). Whole numbers also equal 100.00, but not 100.01
[parameter]=lt100Values that are less than 100
[parameter]=le100Values that are less or equal to 100
[parameter]=gt100Values that are greater than 100
[parameter]=ge100Values that are greater or equal to 100
[parameter]=ne100Values that are not equal to 100

Note that uncertainty does not factor in evaluations, and the precision of the numbers is considered arbitrarily high (the way these search parameters operate here is not the same as whether two numbers are equal to each other in a mathematical sense).

Here are some example searches:

SearchDescription
 GET [base]/Encounter?length=gt20
Search for all the encounters longer than 20 days
 GET [base]/ImmunizationRecommendation?deo-number=2
Search for any immunization recommendation recommending a second dose

2.1.1.4.7 date

A date parameter searches on a date/time or period. As is usual for date/time related functionality, while the concepts are relatively straight-forward, there are a number of subtleties involved in ensuring consistent behavior.

The date parameter format is yyyy-mm-ddThh:nn:ss(TZ) (the standard XML format).

Technically, this is any of the date, dateTime, and instant data types. e.g. Any degree of precision can be provided, but it SHALL be populated from the left (e.g. can't specify a month without a year), except that the minutes SHALL be present if an hour is present, and you SHOULD provide a time zone if the time part is present. Note that the time can be just hours and minutes with no seconds, unlike the XML Schema dateTime type. Some user agents may escape the ":" characters in the URL, and servers SHALL handle this correctly.

Date parameters may be used with the following data types:

dateThe range of the value is the day, month, or year as specified
dateTimeThe range of the value as defined above. e.g. For example, the date 2013-01-10 specifies all the time from 00:00 on 10-Jan 2013 to immediately before 00:00 on 11-Jan 2013
instantAn instant is considered a fixed point in time with an interval smaller than the precision of the system, i.e. an interval with an effective width of 0
PeriodExplicit, though the upper or lower bound may not actually be specified in resources
Timingthe specified scheduling details are ignored and only the outer limits matter. For instance, a schedule that specifies every second day between 31-Jan 2013 and 24-Mar 2013 includes 1-Feb 2013, even though that is on an odd day that is not specified by the period. This is to keep the server load processing queries reasonable

Implicitly, a missing lower boundary is 'less than' any actual date. A missing upper boundary is 'greater than' any actual date. The use of the prefixes:

[parameter]=eq2013-01-14matches 2013-01-14T00:00 (obviously) and also 2013-01-14T10:00 but not 2013-01-15T00:00
[parameter]=ne2013-01-14matches 2013-01-15T00:00 but not 2013-01-14T00:00 or 2013-01-14T10:00
[parameter]=lt2013-01-14T10:00Includes the time 2013-01-14, because it includes the part of 14-Jan 2013 before 10am
[parameter]=gt2013-01-14T10:00Includes the time 2013-01-14, because it includes the part of 14-Jan 2013 after 10am
[parameter]=ge2013-03-14Incldues the period from 21-Jan 2013 onwards, because it may include times after 14-Mar 2013

Other notes:

  • When the date parameter is not fully specified, matches against it are based on the behavior of intervals, where:
    • Dates with just the year specified are equivalent to an interval that starts at the first instant of January 1st to the last instant of December 31st, e.g. 2000 is equivalent to an interval of [2000-01-01T00:00, 2000-12-31T23:59]
    • Dates with the year and month are equivalent to an interval that starts at the first instant of the first day of the month and ends on the last instant of the last day of the month, e.g. 2000-04 is equivalent to an interval of [2000-04-01T00:00, 2000-04-30T23:59]
  • Where possible, the system should correct for timezones when performing queries. Dates do not have time zones, and time zones should not be considered. Where both search parameters and resource element date times do not have time zones, the servers local time zone should be assumed.

To search for all the procedures in a patient compartment that occurred over a 2 year period:

 GET [base]/Patient/23/Procedure?date=ge2010-01-01&date=le2011-12-31

2.1.1.4.8 string

The string parameter refers to simple string searches against sequences of characters. Matches are case- and accent- insensitive. By default, a field matches a string query if the value of the field equals or starts with the supplied parameter value, after both have been normalized by case and accent. The :contains modifier returns results that include the supplied parameter value anywhere within the field being searched. The :exact modifier returns results that exactly match the supplied parameter (the whole string, including casing and accents).

Examples:

[base]/Patient?name=eveany patients with a name containing "eve" at the start of the name. This would include patients with the name "Eve", "Evelyn"
[base]/Patient?name:contains=eveany patients with a name containing "eve" at any position. This would include patients with the name "Eve", "Evelyn", and also "Severine"
[base]/Patient?name:exact=Eveany patients with a name that is exactly "Eve". Note that this would not include patients with the name "eve" or "EVE"

An additional modifier :text can be used to specify a search with advanced text handling (see below) though only a few servers are expected to offer this facility.

It is at the discretion of the server whether to pre-process names, addresses, and contact details to remove separator characters prior to matching in order to ensure more consistent behavior. For example, a server might remove all spaces and "-" characters from phone numbers. What is most appropriate varies depending on culture and context.

2.1.1.4.9 uri

The uri parameter refers to an element which is URI (RFC 3986 ). Matches are precise (e.g. case, accent, and escape) sensitive, and the entire URI must match. The modifier :above or :below can be used to indicate that partial matching is used. For example:

 GET [base]/ValueSet?url=http://acme.org/fhir/ValueSet/123
 GET [base]/ValueSet?url:below=http://acme.org/fhir/

The first is a request to find any value set with the exact url "http://acme.org/fhir/ValueSet/123". The second search will return any value sets that have a URL that starts with "http://acme.org/fhir/". The converse - the search for any value set above a given specific URL - may be useful for searching name systems, but it is generally less useful than the :below search.

2.1.1.4.10 token

A token type is a parameter that searches on a pair, a URI and a value. It is used against code or identifier value where the value may have a URI that scopes its meaning. The search is performed against the pair from a Coding or an Identifier. The syntax for the value is one of the following:

  • [parameter]=[code]: the value of [code] matches a Coding.code or Identifier.value irrespective of the value of the system property
  • [parameter]=[system]|[code]: the value of [code] matches a Coding.code or Identifier.value, and the value of [system] matches the system property of the Identifier or Coding
  • [parameter]=|[code]: the value of [code] matches a Coding.code or Identifier.value, and the Coding/Identifier has no system property

Note that the namespace URI and code both must be escaped. Matches are literal (e.g. not based on subsumption or other code system features), but not case sensitive.

Token search parameters are used for the following data types:

Data Type URI Code Comments
Coding Coding.system Coding.code
CodeableConcept CodeableConcept.coding.system CodeableConcept.coding.code Matches against any coding in the CodeableConcept
Identifier Identifier.system Identifier.value
ContactPoint ContactPoint.use ContactPoint.value The use is prepended by http://hl7.org/fhir/contact-point-system/
code (implicit) code the system is defined in the value set (though it's not usually needed)
boolean (implicit) boolean The implicit system is http://hl7.org/fhir/special-values
string n/a string Token is sometimes used for string to indicate that exact matching is the correct default search stategy

Note about the use of token search parameters for boolean fields: the boolean values 'true' and 'false' are also represented as formal codes in the Special Values code system, which is useful when boolean values need to be represented in a Coding data type. The namespace for these codes is http://hl7.org/fhir/special-values, though there is usually no reason to use this, as a simple true or false is sufficient.

Modifiers:

Modifier Use
:text the search parameter is processed as a string that searches text associated with the code/value - either CodeableConcept.text, Coding.display, or Identifier.type.text
:not reverse the code matching described in the paragraph above
:above the search parameter is a concept with the form [system]|[code], and the search parameter tests whether the coding in a resource subsumes the specified search code (e.g. the search concept has an is-a relationship with the coding in the resource, and this includes the coding itself)
:below the search parameter is a concept with the form [system]|[code], and the search parameter tests whether the coding in a resource is subsumed by the specified search code (e.g. the coding in the resource has an is-a relationship with the search concept, and this includes the coding itself)
:in the search parameter is a URI (relative or absolute) that identifies a value set, and the search parameter tests whether the coding is in the specified value set. The reference may be literal (to an address where the value set can be found) or logical (a reference to ValueSet.url) - if the server can treat the reference as a literal URL, it does, else it tries to match known logical ValueSet.url values
:not-in the search parameter is a URI (relative or absolute) that identifies a value set, and the search parameter tests whether the coding is not in the specified value set

Most servers will only process value sets that are already known/registered/supported internally, but servers can elect to accept any valid reference to a value set. Servers may elect to consider concept mappings when testing for subsumption relationships.

Here are some example searches:

SearchDescription
 GET [base]/Patient?identifier=http://acme.org/patient|2345
Search for all the patients with an identifier with key = "2345" in the system "http://acme.org/patient"
 GET [base]/Patient?gender=male
Search for any patient with a gender that has the code "male"
 GET [base]/Patient?gender:not=male
Search for any patient with a gender that does not have the code "male"
 GET [base]/Patient?active=true
Search for any patients that are active
 GET [base]/Condition?code=http://acme.org/conditions/codes|ha125
Search for any condition with a code "ha125" in the code system "http://acme.org/conditions/codes"
 GET [base]/Condition?code=ha125
Search for any condition with a code "ha125". Note that there is not often any useful overlap in literal symbols between code systems, so the previous example is generally preferred
 GET [base]/Condition?code:text=headache
Search for any Condition with a code that has a text "headache" associated with it (either in the text, or a display)
 GET [base]/Condition?code:in=http://snomed.info/sct?fhir_vs=isa/126851005
Search for any condition in the SNOMED CT value set that includes all descendents of "Neoplasm of liver"
 GET [base]/Condition?code:below=126851005
Search for any condition that is subsumed by the SNOMED CT Code "Neoplasm of liver". Note: this is the same outcome as the previous search
 GET [base]/Condition?code:in=http://acme.org/fhir/ValueSet/cardiac-conditions
Search for any condition that is in the institutions list of cardiac conditions

2.1.1.4.11 quantity

A quantity parameter searches on the Quantity data type. The syntax for the value follows the form:

  • [parameter]=[prefix][number]|[system]|[code] matches a quantity with the given unit

The prefix optional, and is as described above, both regarding how precision and comparator/range operators are interpreted. Example searches:

SearchDescription
 GET [base]/Observation?value=5.4|http://unitsofmeasure.org|mg
Search for all the observations with a value of 5.4 mg where mg is understood as a UCUM unit (system/code)
 GET [base]/Observation?value=5.4||mg
Search for all the observations with a value of 5.4 mg where the units - either the code or the stated human units (units) are "mg"
 GET [base]/Observation?value=le5.4|http://unitsofmeasure.org|mg
Search for all the observations where the value of is less than 5.4 mg where mg is understood as a UCUM unit
 GET [base]/Observation?value=ap5.4|http://unitsofmeasure.org|mg
Search for all the observations where the value of is about 5.4 mg where mg is understood as a UCUM unit

The search processor may choose to perform a search based on canonical units (e.g. any value where the units can be converted to a value in mg in the case above)

2.1.1.4.12 reference

A reference parameter refers to references between resources, e.g. find all Conditions where the subject reference is a particular patient, where the patient is selected by name or identifier. The interpretation of a reference parameter is either:

  • [parameter]=[id] the logical [id] of a resource using a local reference (i.e. a relative reference)
  • [parameter]=[type]/[id] the logical [id] of a resource of a specified type using a local reference (i.e. a relative reference), for when the reference can point to different types of resources (e.g. Observation.subject)
  • [parameter]=[url] where the [url] is an absolute URL - a reference to a resource by its absolute location

Note that if a relative reference resolves to the same value as a specified absolute URL, or vice versa, this is a match too. For example, if the search parameter value is Patient/123, then this will find references like this:

 <patient>
   <reference value="Patient/123"/>
 </patient>

If the server base address is http://example.org/fhir, then the full URL for that reference is http://example.org/fhir/Patient/123, which means that the search term also matches patient references like this:

 <patient>
   <reference value="http://example.org/fhir/Patient/123"/>
 </patient>

In addition, searching for reference=http://example.org/fhir/Patient/123 will also match both references.

Some references are allowed to point to more than one type of resource. e.g. subject : Reference(Patient|Group|Device|..). In these cases, multiple different resources may have the same logical identifier. Servers SHOULD reject a search where the logical id refers to more than one matching resource across different types. In order to allow the client to perform a search in these situations can specify the type explicitly:

 GET [base]/Condition?subject=Patient/23

This searches for any conditions where the subject refers to the patient resource with the logical identifier "23". A modifier is also defined to to allow the client to be explicit about the intended type:

 GET [base]/Condition?subject:Patient=23

This has the same effect as the previous search. The modifier becomes useful when used with chaining as in explained in the next section. Note that the [type] modifier can't be used with a reference to a resource found on another server, since the server would not usually know what type that resource has (but since these are absolute references, there can be no ambiguity about the type).

2.1.1.4.13 Chained parameters

In order to save a client from doing a series of search operations, reference parameters may be "chained" by appending them with a period (.) followed by the name of a search parameter defined for the target resource. This can be done recursively, following a logical path through a graph of related resources, separated by ".". For instance, given that the resource DiagnosticReport has a search parameter named subject, which is usually a reference to a Patient resource, and the Patient resource includes a parameter name which searches on patient name, then the search

 GET [base]/DiagnosticReport?subject.name=peter

is a request to return all the lab reports that have a subject whose name includes "peter". Because the Diagnostic Report subject can be one of a set of different resources, it's necessary to limit the search to a particular type:

 GET [base]/DiagnosticReport?subject:Patient.name=peter

Which is a request to return all the lab reports that have a subject which is a patient, whose name includes "peter".

Advanced Search Note: Where a chained parameter searches a resource reference that may have more than one different type of resource as its target, the parameter chain may end up referring to search parameters with the same name on more than one kind of resource at once. Servers SHOULD reject a search where the logical id refers to more than one matching resource across different types (e.g. the client has to specify the type explicitly using the syntax in the second example above).

2.1.1.4.14 Composite Search Parameters

Composite search parameters supports joining single values with a "$". For example, the result of the search operation is the intersection of the resources that match the criteria specified by each individual search parameter. If a parameter repeats, such as /Patient?language=FR&language=NL, then this matches a patient who speaks both languages. This is known as an AND search parameter, since the server is expected to respond only with results which match both values.

If, instead, the search is to find patients that speak either language, then this is a single parameter with multiple values, separated by a ','. For example: "/Patient?language=FR,NL". This is known as an OR search parameter, since the server is expected to respond with results which match either value.

AND parameters and OR parameters may also be combined, for example: "/Patient?language=FR,NL&language=EN" would refer to any patient who speaks English as well as either French or Dutch.

This allows for simple combinations of and/or values, but doesn't allow a search based on a pair of values, such as all observations with a sodium value >150 mmol/L (particularly as the end criteria of a chained search), or searching on Group.characteristic: you need find a combination of key/value, not an intersection of separate matches on key and value. Another example is spatial coordinates when doing geographical searches.

To allow these searches, a resource may also specify composite parameters that take sequences of single values that match other defined parameters as an argument. The matching parameter of each component in such a sequence is documented in the definition of the parameter. These sequences are formed by joining the single values with a "$". Note that this sequence is a single value and itself can be composed into a set of values, so that, for example, multiple matching state-on-date parameters can be specified as state-on-date=new$2013-05-04,active$2013-05-05.

Modifiers are not used on composite parameters.

Examples of using composite parameters:

Search for all groups that have a characteristic 'gender' with a text value of 'mixed'
SearchDescription
 GET [base]/DiagnosticReport?result.code-value-quantity=http://loinc.org|2823-3$gt5.5|http://unitsofmeasure.org|mmol/L
Search for all diagnostic reports that contain on observation with a potassium value of >5.4 mmol/L (UCUM)
 GET [base]/Observation?component-code-value-quantity=http://loinc.org|8480-6$lt60
Search for all the observations with a systolic blood pressure < 60. Note that in this case, the units are assumed (eveyone uses mmHg)
 GET [base]/Group?characteristic-value=gender$mixed

2.1.1.4.15 Escaping Search Parameters

In the rules above, special rules are defined for the characters "$", ",", and "|". As a consequence, if these characters appear in an actual parameter value, they must be differentiated from their use as separator characters. When any of these characters appear in an actual parameter value, they must be prepended by the character "\" (which also must be used to prepend itself). So "param=xxx$xxx" means a composite parameter, while "param=xx\$xx" means that the parameter has the literal value 'xx$xx'. The parameter value "xx\xx" is illegal, and the parameter value "param=xx\\xx" means a literal value of 'xx\xx'.

This specification defines this extra form of escape for a reason. The classic %xx escaping which is part of normal HTTP URLs makes sure the character ends up at the FHIR server correctly, while the "," versus "\" becomes important once it has reached the server and the query is parsed. So:

GET [base]/ValueSet?url=http://acme.org/fhir/ValueSet/123,http://acme.org/fhir/ValueSet/124%2CValueSet/125

uses url escaping to make sure the FHIR server received:

GET [base]/ValueSet?url=http://acme.org/fhir/ValueSet/123,http://acme.org/fhir/ValueSet/124,125

This means that the server is comparing the url against 3 values (the last one being a relative (and wrong) url, which is probably not the actual intent). However:

GET [base]/ValueSet?url=http://acme.org/fhir/ValueSet/123,http://acme.org/fhir/ValueSet/124\,125

which is equivalent to:

GET [base]/ValueSet?url=http://acme.org/fhir/ValueSet/123,http://acme.org/fhir/ValueSet/124\%2C125

which would mean: url = "http://.....123" OR "http://....124,125".

2.1.1.4.16 Text Search Parameters

There are two special text search parameters, _text and _content, which search on the narrative of the resource, and the entire content of the resource respectively. These parameters SHOULD support a sophisticated search functionality of the type offered by typical text indexing services is appropriate. The value of the parameter is a text based search, which may involve searching multiple words with thesaurus and proximity considerations, and logical operations such as AND, OR etc. For example:

 GET [base]/Condition?_text=(bone OR liver) and metastases

This searches for all Condition resources with the word "metastases" and either "bone" or "liver" in the narrative. The server MAY choose to search for related words as well.

DSTU Note: The issues around standardizing text search are not fully resolved. During the trial use period for this specification, we recommend that systems use the rules specified by the OData specification for the $search parameter . Typical implementations would use Lucene, an sql-based full text search, or some indexing service.

Feedback is welcome here .

2.1.1.4.17 Searching by list

The _list parameter allows for the retrieval of resources that are referenced by a List resource.

 GET [base]/Patient?_list=42

This returns all patient resources that are referenced from the list found at [base]/List/42) in List.entry.item. While it is possible to retrieve the list, and then iterate the entries in the list fetching each patient, using a list as a search criteria allows for additional search criteria to be specified. For instance:

 GET [base]/Patient?_list=42&gender=female

which means, welect all the female patients in the list. The server can return the list referred to in the search parameter as an included resource, but is not required to do so. In addition, a system can support searching by lists by their logical function. For example:

 GET [base]/AllergyIntolerance?patient=42&_list=$current-allergies

This is a request to fetch all the allergies in the patient 42's "Currrent Allergy List". The server returns all the relevant AllergyIntolerance resources, and can also choose to return the list. For further information, refer to the definition of "$current-allergies", and the List Operation "Find". Note that servers are not required to make these lists available to the clients as list resources, but may choose to do so.

2.1.1.4.18 Advanced filtering

The search mechanism described above is flexible, and easy to implement for simple cases, but it is limited in its ability to express combination queries. To complement this mechanism, a specific search expression parameter can also be used, named "_filter".

For example, this is a moderately simple search: find all the observations for patient with a name including "peter" that have a LOINC code 1234-5:

GET [base]/Observation?name=http://loinc.org|1234-5&subject.name=peter

Using the _filter parameter, the search would be expressed like this:

GET [base]/Observation?_filter=name eq http://loinc.org|1234-5 and subject.name co "peter"

The _filter parameter is described in detail on the "_Filter Parameter" page.

2.1.1.5 Managing Returned Resources

2.1.1.5.1 Sorting

The client can indicate which order to return the results in using the parameter "_sort", which can have a value of one of the search parameters. The _sort parameter can repeat to indicate sort order, with the repeats indicating a lower sort priority sequentially.

The _sort parameter takes one of two qualifiers, ":asc" and ":desc", which specify ascending and descending sort order respectively. The default value is ":asc".

Notes:

  • When sorting, the actual sort value used is not returned explicitly by the server for each resource, just the resource contents
  • To sort by relevance, use "_sort:asc=_score"
  • The server returns the sort it performs as part of the returned search parameters (see below)
  • A search parameter can refer to an element that repeat, and therefore there can be multiple values for a given search parameter for a single resource. In this case, the sort is based on the item in the set of multiple parameters that comes earliest in the specified sort order when ordering the returned resources.
  • When sorting on string search parameters, sorting SHOULD be performed on a case-insensitive basis. Accents may either be ignored or sorted as per realm convention. Note: Consistency of sorting across servers isn't as essential as consistency of filtering (even that is variable). The purpose of sorting is to provide data in a "reasonable" order for end users. "Reasonable" may vary by realm, particularly for accented characters.

2.1.1.5.2 Page Count

In order to keep the load on clients, servers and the network minimized, the server may choose to return the results in a series of pages. The search result set contains the URLs that the client uses to request additional pages from the search set. For a simple RESTful search, the page links are contained in the returned bundle as links.

Typically a server will provide its own parameters in the links that it uses to manage the state of the search as pages are retrieved. These parameters do not need to be understood or processed by the client.

The parameter _count is defined as a hint to the server regarding how many resources should be returned in a single page. Servers SHALL NOT return more resources than requested (even if they don't support paging) but are allowed to return less than the client asked for. The server should repeat the original _count parameter in its returned page links so that subsequent paging requests honour the original _count. Note that it is at the discretion of the search engine how to handle ongoing updates to the resources while the search is proceeding.

Note that the combination of _sort and _count can be used to return just the latest resource that meets a particular criteria - set the critera, and then sort by date in descending order, with _count=1. This way, the last matching resource will be returned.

2.1.1.5.3 Including other resources in result (_include and _revinclude)

Clients may request that the engine return additional resources related to the search results, in order to reduce the overall network delay of repeated retrievals of related resources. A typical case where this is useful is where the client is searching on some type of clinical resource, but for every such resource returned, the client will also need the subject (patient) resource that the clinical resource refers to. The client can use the _include parameter to indicate that the subject resources be included in the results. An alternative scenario is where the client wishes to fetch a particular resource, and any resources that refer to it. For example, the client may wish to fetch a MedicationOrder, and any provenance resources that refer to the prescription. This is known as a reverse include, and specified by providing a _revinclude parameter.

Both _include and _revinclude are based on search parameters, rather than paths in the resource, since joins (e.g. chaining are already done by search parameter.

Each _include parameter specifies a search parameter to join on:

 GET [base]/MedicationOrder?_include=MedicationOrder:patient&criteria...
 GET [base]/MedicationOrder?_revinclude=Provenance:target&criteria...

The first search means, for any matching MedicationOrder, include any patient that the medication prescriptions in the result set refer to. The second search means, for any matching prescriptions, return all the provenance resources that refer to them.

Parameter values for both _include and _revinclude have 3 parts, separated by a ":" separator:

  1. The name of the source resource from which the join comes
  2. The name of the search parameter which must be of type reference
  3. (Optional) A specific of type of target resource (for when the search parameter refers to multiple possible target types)

_include and _reverseInclude parameters do not include multiple values. Instead, the parameters are repeated for each different include criteria.

For each returned resource, the server identifies the resources that meet the criteria expressed in the join, and adds to the results, with the entry.status set to "include" (in some searches, it is not obvious which resources are matches, and which are includes).

The inclusion process can be recursive, if the modifier :recurse is included. For example, this example search returns all the Medication Prescription resources and their prescribing Practitioner Resources for the matching Medication Dispense resources:

GET [base]/MedicationDispense?_include=MedicationDispense.authorizingPrescription
    &_include:recurse=MedicationOrder.prescriber&criteria...

This technique applies to circular relationships as well. For example, the first of these two searches includes any related observations to the target relationships, but only those directly related. The second search asks for the _include based on related parameter to be executed recursively, so will retrieve observations that are directly related, and also any related observations to any other included observation.

GET [base]/Observation?_include=Observation.related-target&criteria...
GET [base]/Observation?_include:recurse=Observation.related-target&criteria...

Both _include and _reverseInclude and use the wild card "*" for the search parameter name, indicating by this that any search parameter of type=reference be included, though though both clients and servers need to take care not to request or return too many resources when doing this. Most notably, using recursive inclusions might lead to the retrieval of the full patient's record, or even more: resources are organized into an interlinked network and broad _include paths may eventually traverse all possible paths on the server. For servers, these recursive and wildcard _includes are demanding and may slow the search response time significantly.

It is at the server's discretion how deep to recursively evaluate the inclusions. Servers are expected to limit the number of iterations done to an appropriate level and are not obliged to honor requests to include additional resources in the search results.

When the search results are paged, each page of search results should include the matching includes for the resources in each page, so that each page stands alone as a coherent package.

2.1.1.5.4 Contained Resources

By default, search results only include resources that are not contained in other resources. A chained condition will be evaluated inside contained resources. To illustrate this, consider a MedicationOrder resource that has a contained Medication resource specifying a custom formulation that has ingredient that has a value Substance/x23. In this case, a search:

GET MedicationOrder?medication.ingredient=Substance/x23

will include the MedicationOrder resource in the results. However this search:

GET Medication?ingredient=Substance/x23

will not include the contained Medication resource in the results, since either the wrong type of resource would be returned, or the contained resource would be returned without its container resource, which provides context to the contained resource.

Clients are able to modify this behavior using the _contained parameter, which can have one of the following values:

  • false (default): Do not return contained resources
  • true: return only contained resources
  • both: return both contained and non-contained (normal) resources

When contained resources are being returned, the server should return either the container resource, or the contained resource alone. The client can specify which by using the _containedType parameter, which can have one of the following values:

  • container (default): Return the container resources
  • contained: return only the contained resource

When returning a container resource, the server simply puts this in the search results:

<Bundle>
  ...
  <entry>
    <resource>
      <MedicationOrder>
        <id value="23">
        ....
        <contained>
          <Medication>
            <id value="m1">
            ...
          </Medication>
        <contained>

      </MedicationOrder>
    </resource>
    <search>
      <mode value="match"/>
    </search>
  </entry>
</Bundle>

In the case of returning container resources, the server SHALL populate the entry.search.mode element so that the client can pick matches and includes apart (the usual approach of doing it by type may not work). If the return type is the contained resource, this must be done slightly differently:

<Bundle>
  ...
  <entry>
    <fullUrl value="http://example.com/fhir/MedicationOrder/23#"/>
    <resource>
      <Medication>
        <id value="m1">
        ...
      </Medication>
    </resource>
    <search>
      <mode value="match"/>
    </search>
  </entry>
</Bundle>

In this case, the fullUrl informs the client that this is a contained resource, and the identity of the containing resource.

2.1.1.5.5 External References

If the _include path selects a reference that refers to a resource on another server, the server can elect to include that resource in the search results for the convenience of the client.

If the _include path selects a reference that refers to an entity that is not a Resource (e.g. an image attachment), the server may also elect to include this in the returned results as a Binary resource. For example, the include path may point to an attachment which is by reference, like this:

 <content>
   <contentType>image/jpeg</contentType>
   <url>http://example.org/images/2343434/234234.jpg</url>
 </content>

The server can retrieve the target of this reference, and add this to the results for the convenience of the client.

DSTU Note: Should additional rules about how _include works be made?

Feedback based on implementation experience is sought here .

2.1.1.5.6 Paging

When returning paged results for a search with _include resources, all _include resources that are related to the primary resources returned for the page SHOULD also be returned as part of that same page, even if some of those resource instances have previously been returned on previous pages. This allows both sender and receiver to avoid caching results of other pages.

2.1.1.5.7 Summary

The client can request the server to return a portion of the resources only using the parameter "_summary":

   GET [base]/ValueSet?_summary=true

The _summary parameter requests the server to return only a subset of the resource. It can have one of the following values:

trueReturn only those elements marked as 'summary' in the base definition of the resource(s)
textReturn only the 'text' element, and any mandatory elements
dataRemove the text element
countSearch only: just return a count of the matching resources, without returning the actual matches
falseReturn all parts of the resource(s)

The intent of the _summary parameter is to reduce the total processing load on server, client, and resources between them such as the network. It is most useful for resources that can be large, particularly ones that include images or elements that may repeat many times. The purpose of the summary from is to allow a client to quickly retrieve a large set of resources, and let a user pick the appropriate one. The summary for an element is defined to allow a user to quickly sort and filter the resources, and typically omit important content, on the basis that the entire resource will be retrieved when the user selects a resource.

Servers are not obliged to return just a summary as requested. There is only a limited number of summary forms defined for resources in order to allow servers to store the summarized form(s) in advance. Servers SHOULD mark the resources with the tag SUBSETTED to ensure that the incomplete resource is not acidentally used to overwrite a complete resource.

2.1.1.5.8 Elements

If one of the summary views defined above is not appropriate, a client can request a specific set of elements be returned as part of a resource using the _elements parameter:

   GET [base]/Patient?_elements=identifier,active,link

The _elements parameter consists of a comma separated list of base element names (e.g. elements defined at the root level in the resource). Only elements that are listed are to be returned. Clients SHOULD list all mandatory elements in a resource as part of the list of elements. The list of elements does not apply to included resources.

Servers are not obliged to return just the requested elements. Servers SHOULD always return mandatory elements whether they are requested or not. Servers SHOULD mark the resources with the tag SUBSETTED to ensure that the incomplete resource is not actually used to overwrite a complete resource.

2.1.1.5.9 Relevance

Where a search specifies a non-deterministic sort, the search algorithm may generate some kind of ranking score to indicate which resources meet the specified criteria better than others. The server can return this score in entry.score:

  <entry>
    <score value=".45"/>
    <Patient>
      ... patient data ...
    </Patient>
  </entry>

The score is a decimal number with a value between (and including) 0 and 1, where 1 is best match, and 0 is least match.

2.1.1.6 Server Conformance

In order to allow the client to be confident about what search parameters were used as a criteria by the server, the server SHALL return the parameters that were actually used to process the search. Applications processing search results SHALL check these returned values where necessary. For example, if the server did not support some of the filters specified in the search, a client might manually apply those filters to the retrieved result set, display a warning message to the user or take some other action.

In the case of a RESTful search, these parameters are encoded in the self link in the bundle that is returned:

  <link>
    <relation value="self"/>
    <url value="http://example.org/Patient?name=peter"/>
  </link>

In other respects, servers have considerable discretion with regards to supporting search:

  • Servers can choose which parameters to support (other than _id above)
  • Servers can choose when and where to implement parameter chaining, and when and where they support the _include parameter
  • Servers are able to declare additional parameters in the profiles referenced from their conformance statements. Servers should define search parameters starting with a "-" character to ensure that the names they choose do not clash with future parameters defined by this specification
  • Servers are not required to enforce case sensitivity on parameter names, though the names are case sensitive (and URLs are generally case-sensitive)
  • Servers may choose how many results to return, though the client can use _count as above
  • Servers can choose how to sort the return results, though they SHOULD honor the _sort parameter

2.1.1.7 Advanced Search

The search framework described above is a useful framework for providing a simple search based on indexed criteria, but more sophisticated query capability is needed to handle precise queries, complex decision support based requests, and direct queries that have human resolution.

More advanced search operations are specified by the _query parameter:

   GET [base]/Patient?_query=name&parameters...

The _query parameter names a custom search profile that describes a specific query operation. The named query may define additional named parameters that are used with that particular named query. Servers can define their own additional named queries to meet their own uses using a OperationDefinition.

There can only ever be one _query parameter in a set of search parameters. Servers processing search requests SHALL refuse to process a search request if they do not recognize the _query parameter value.

2.1.1.8 Search Result Currency

The results of a search operation are only guaranteed to be current at the moment the operation is executed. After the operation is executed, ongoing actions performed on the resources against which the search was executed will render the results increasingly stale. The significance of this depends on the nature of the search, and the kind of use that is being made of the results.

This is particularly relevant when the server is returning the results in a series of pages. It is at the discretion of the search engine how to handle ongoing updates to the resources while the search is proceeding.

Note that performing a search operation does not change the set of resources on the server, with the exception of the creation of Audit Event resources auditing the search itself.

2.1.1.9 Summary Tables

Common Parameters defined for all resources:
NameTypeDescriptionPaths
_idstringResource id (not a full URL)Resource.id
_lastUpdateddateDate last updated. Server has discretion on the boundary precisionResource.meta.lastUpdated
_tagtokenSearch by a resource tagResource.meta.tag
_profileuriSearch for all resources tagged with a profileResource.meta.profile
_securitytokenSearch by a security labelResource.meta.security
_textstringText search against the narrative
_contentstringText search against the entire resource
_liststringAll resources in nominated list (by id, not a full URL)
_querystringCustom named query
Search Control Parameters:
NameTypeDescriptionAllowable Content
_sortstringOrder to sort results in (can repeat for inner sort orders)The name of a valid search parameter
_countnumber Number of results per pageWhole Number
_includestringOther resources to include in the search results that search matches point toSourceType:searchParam(:targetType)
_revincludestringOther resources to include in the search results when they refer to search matchesSourceType:searchParam(:targetType)
_summarystringJust return the summary elements (for resources where this is defined)true | false (false is default)
_containedstringWhether to return resources contained in other resources in the search matchestrue | false | both (false is default)
_containedTypestringIf returning contained resources, whether to return the contained or container resourcescontainer | contained

Cross-map between search parameter types and Data types:

Data Type number date string token reference quantity uri
boolean N N N Y . true|false (System = http://hl7.org/fhir/special-values but not usually needed) N N N
code N N N Y . (System, if desired, is defined in the underlying value set for eeach code) N N N
date N Y N N N N N
dateTime N Y N N N N N
instant N Y N N N N N
integer Y N N N N N N
string N N Y Y N N N
uri N N N N Y N Y
Address N N Y search on any elements in the address N N N N
Annotation N N N N N N N
CodeableConcept N N N Y N N N
Coding N N N Y N N N
ContactPoint N N N Y N N N
Duration N N N N N N N
HumanName N N Y Search on any element in the name N N N N
Identifier N N N Y N N N
Period N Y N N N N N
Quantity Y N N N N Y N
Range N N N N N N N
Reference N N N N Y N N
SampledData N N N N N N N
Timing N Y N N N N N