This page is part of the FHIR Specification (v0.4.0: DSTU 2 Draft). 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
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.
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. The server returns the results in the HTTP response as a bundle (in XML, an atom feed) which includes the resources that are the results of the search. The server can also include additional resources in the result set, such as OperationOutcome resources. Clients should ignore resources that don't have the expected type. 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.
Search operations are executed in one of 3 defined contexts that control which set of resources are being searched:
Search operations can also be initiated by other more complex and flexible methods described below, which change both the way the search is initiated, and the results that are returned.
These parameters are defined that apply to all resources: _id, _language, _lastUpdated, _profile, _security, _tag.
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
except that it returns a bundle with the requested resource, rather than the resource itself. Additional parameters can be added which may provide additional functionality on top of this base read equivalence.
The search parameter _language refers to the base language of the resource:
GET [base]/Composition?_language=fr
This search finds any composition with a designated language of French. Note that this is the claimed language of the resource, not the actual language of the content.
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/Profile/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).
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.
Each search parameter is defined with a type that defines how the search parameter behaves. These are the defined parameter types:
number | Search parameter SHALL be a number (a whole number, or a decimal). |
date | Search parameter is on a date/time. The date format is the standard XML format, though other formats may be supported. |
string | Search 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. |
token | Search 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. |
reference | A reference to another resource. |
composite | A composite search parameter that combines a search on two values together. |
quantity | A search parameter that searches on a quantity. |
The search parameters can also have "modifiers" appended to them that control their behavior. The kind of modifiers that can be used depend on the type of parameter.
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:
The prefixes >, >=, <=, and < may be used on the parameter value, and have the usual meaning (note that "=" must be URL-encoded in the value in a URL). Examples:
[parameter]=100 | Values that equal 100, to 2 significant figures precision, so range [99.5 ... 100.5) |
[parameter]=100.00 | Values that equal 100, to 4 significant figures precision, so range [99.995 ... 100.005). Whole numbers also equal 100.00, but not 100.01 |
[parameter]=<100 | Values that are less than 100 |
[parameter]=<=100 | Values that are less or equal to 100 |
[parameter]=>100 | Values that are greater than 100 |
[parameter]=>=100 | Values that are greater or equal to 100 |
[parameter]=!=100 | Values that are not equal to 100. Precision works as for equals (this operation is the logical converse of equals) |
For comparisons involving < or >, uncertainty does not factor, and the precision of the numbers is considered arbitrarily high. Note that the way these search parameters operate here is not the same as whether two numbers are equal to each other in a mathematical sense.
A date parameter searches on a date/time or period. The prefixes >, >=, <=, and < may be used on the parameter value, and have the usual meaning. However, 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.
As an example, the following search searches for all the procedures in a patient compartment that occurred over a 2 year period:
GET [base]/Patient/23/Procedure?date=>2010-01-01&date=<2011-12-31
The string parameter refer to simple string searches against sequences of characters. Matches are case- and accent- insensitive. By default, a match exists if a portion of the parameter value contains the specified string. It is at the discretion of the server whether to do a left-partial search. The modifier :exact can be used to indicate that the match needs to be exact (the whole string, including casing and accents). For example:
GET [base]/Patient?name=eve GET [base]/Patient?name:exact=Eve
The first is a request to find any patients with "eve" in any part of the name. This would include patients with the name "Eve", "Severine", etc. The second search would only return patients with the name "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.
A token type is a parameter that searches on a code or identifier value where the value may have a URI that scopes its meaning (from a Coding, a CodeableConcept or an Identifier type, and also from a code where the URI is implicit).
If the parameter has no modifier, the search is performed against the URI/value from a Coding or an Identifier. The syntax for the value is one of the following:
Note that the namespace URI and code both must be escaped.
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.label |
: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) |
: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) |
: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 referecnce to ValueSet.identifier) |
: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:
Search | Description |
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 a code "male", irrespective of the system. Note that this usually isn't very useful - systems generally define symbols where overlap is coincidental and not informative |
GET [base]/Patient?gender=http://hl7.org/fhir/v2/0001|M | Search for any patient with a gender which is coded as "M" in the HL7 Administrative Gender table |
GET [base]/Patient?gender:text=male | Search for any patient with a gender that has a text "male" associated with it (note: this will include "female") |
A quantity parameter searches on the Quantity data type. The syntax for the value follows the form:
The comparator is optional; if it is not present, the default comparator is "=". A special value "~" can be used for approximation. Example searches:
Search | Description |
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=<5.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=~5.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 recommended value for the approximation is 10% of the stated value, but systems may choose other values where appropriate |
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)
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:
Note that if a relative reference resolves to the same value as a specified absolute URL, or vice versa, this is a match too.
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. In this case, the client can specify a type modifier after the name of the parameter to be explicit about the intended type:
GET [base]/Condition?subject:Patient=23
This searches for any conditions where the subject refers to the patient resource with the logical identifier "23". The server SHOULD reject a search where the logical id refers to more than one matching resource across different types. 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).
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 possible 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. The parameter names defined in FHIR have consistent types wherever they are used. Implementers defining their own names need to be sure that they do not create unprocessable combinations. Servers SHOULD reject queries chained queries that lead to disjoint types along the path (e.g. the client has to specify the type explicitly using the syntax in the second example above).
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.
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'.
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 a forth coming release of the OData specification for the $search parameter. Typical implementations would use Lucene, an sql-based full text search, or some indexing service. Feedback about consistent implementation in this area is welcome.
The search mechanism described above is flexible, and easy to implement for simple cases, but it is limited in it's 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.
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.
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:
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. Note that it is at the discretion of the search engine how to handle ongoing updates to the resources while the search is proceeding.
Clients may request that the engine return additional resources related to the search results, in order to reduce the overall network delay. 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 requests that the subject resources be included in the results set by providing one or more _include parameters.
Each _include parameter specifies a path to a url (usually a resource reference):
GET [base]/MedicationDispense?_include=MedicationDispense.authorizingPrescription &_include=MedicationPrescription.prescriber&criteria...
For each returned resource, the server collects the elements described by the path, and any resources they point to that the server also holds are added 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). This example search returns all the Medication Prescription resources and their prescribing Practitioner Resources for the matching Medication Dispense resources.
An include path begins at the root of a FHIR resource and must include exactly one property of type Reference or uri, which must appear in the terminal position. That means that an include path cannot "cross the boundary" from one resource to another. So for example, `CarePlan.activity.simple.performer` is a valid include path, because it begins at the root of the CarePlan resource and ends with a reference to another resource (Practitioner|Organization|RelatedPerson|Patient). On the other hand, `CarePlan.patient.managingOrganization` is an invalid include path, because it includes two References (patient and managingOrganization), and `CarePlan.goal` is an invalid include path because it does not end with a Reference or a URI.
When looking for the references indicated by an include path, all occurrences of the component last encountered on the that path need to be considered, including occurrences of that same component reachable via deeper (nested) relations. An example is the include path Composition.section.content, where the content reference on the highest level Section is included, but also those reachable via the nested section relationship. Likewise, Questionnaire.group.subject will return all subject on all Groups, including those reachable by the deeper path via the nested Question and nested Groups within those questions.
Include paths may include wild cards, such as MedicationDispense.results.*, or even _include=*, though both clients and servers need to take care not to request or return too many resources when doing this. Most notably, re-applying inclusion paths over newly included resources might lead to cycles or the retrieval of the full patient's file: 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. Servers are expected to limit the number of iterations done and are not obliged to honor requests to include additional resources in the search results.
Note: for a server, it would generally only be required perform one iteration per _include parameter
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: HL7 is seeking feedback from implementers about whether additional rules should be made about how _include works, based on implementation experience.
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.
The client can request the server to return a summary portion of the resources only using the parameter "_summary":
GET [base]/ValueSet?_summary=true
The _summary parameter requests the server to return only the elements marked as "summary" in their definition. This is used 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.
Servers are not obliged to return just a summary, and summaries are not defined for resources where there is no need for summarization. There is only one summary form defined for each resource in order to allow servers to store the summarized form in advance.
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 atom feed 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:
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¶meters...
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.
In addition to the standard search operation on a RESTful interface (as described above), searches can also be performed using the messaging framework.
TODO: describe how this is done
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 Security Event resources auditing the search itself.