Search

Last updated 2 months ago

Overview

Search is a base FHIR operation. Search is used to filter and receive linked entities.

Base search structure looks like this:

GET [base]/[type]?name=value&...{&_format=[mime-type]}}

Simple search by patient name:

GET /Patient?name=Max

For optimization of search results, we can specify fields of the output bundle:

GET /Patient?_elements=id,birthDate

All sample requests can be run in Postman:Run in Postman

Search Parameters

Some search parameters are available for all resources:

  • _id logical id of entity

  • _lastUpdated last modification time

  • _text filter on resource narrative

  • _content filter on resource content

A list of available search parameters for specific resource can be obtained via the following request:

Request
Response
GET /SearchParameter?resource=Patient&_elements=name
resourceType: Bundle
type: searchset
params:
- resourceType: SearchParameter
type: param
name: resource
modifier: null
values:
- {value: Patient}
search-param:
name: resource
type: reference
expression:
- [resource]
resource: {resourceType: Entity, id: SearchParameter}
module: proto
typedExpression:
- path: [resource]
type: Reference
- type: elements
exclude: false
value:
name: {}
query-sql: ['SELECT "searchparameter".* FROM "searchparameter" WHERE knife_extract_text("searchparameter".resource,
?) && ARRAY[?] LIMIT ? OFFSET ?', '[["resource","id"]]', Patient, 100, 0]
query-time: 10
entry:
- resource: {name: address-city, resourceType: SearchParameter}
fullUrl: https://example.aidbox.app/SearchParameter/
- resource: {name: active, resourceType: SearchParameter}
fullUrl: https://example.aidbox.app/SearchParameter/
- resource: {name: given, resourceType: SearchParameter}
fullUrl: https://example.aidbox.app/SearchParameter/
- resource: {name: address-state, resourceType: SearchParameter}
fullUrl: https://example.aidbox.app/SearchParameter/
- resource: {name: general-practitioner, resourceType: SearchParameter}
fullUrl: https://example.aidbox.app/SearchParameter/
- resource: {name: gender, resourceType: SearchParameter}
fullUrl: https://example.aidbox.app/SearchParameter/
- resource: {name: name, resourceType: SearchParameter}
fullUrl: https://example.aidbox.app/SearchParameter/
- resource: {name: family, resourceType: SearchParameter}
fullUrl: https://example.aidbox.app/SearchParameter/
- resource: {name: telecom, resourceType: SearchParameter}
fullUrl: https://example.aidbox.app/SearchParameter/
- resource: {name: animal-species, resourceType: SearchParameter}
fullUrl: https://example.aidbox.app/SearchParameter/
- resource: {name: identifier, resourceType: SearchParameter}
fullUrl: https://example.aidbox.app/SearchParameter/
- resource: {name: link, resourceType: SearchParameter}
fullUrl: https://example.aidbox.app/SearchParameter/
- resource: {name: address-use, resourceType: SearchParameter}
fullUrl: https://example.aidbox.app/SearchParameter/
- resource: {name: language, resourceType: SearchParameter}
fullUrl: https://example.aidbox.app/SearchParameter/
- resource: {name: phonetic, resourceType: SearchParameter}
fullUrl: https://example.aidbox.app/SearchParameter/
- resource: {name: death-date, resourceType: SearchParameter}
fullUrl: https://example.aidbox.app/SearchParameter/
- resource: {name: animal-breed, resourceType: SearchParameter}
fullUrl: https://example.aidbox.app/SearchParameter/
- resource: {name: deceased, resourceType: SearchParameter}
fullUrl: https://example.aidbox.app/SearchParameter/
- resource: {name: address, resourceType: SearchParameter}
fullUrl: https://example.aidbox.app/SearchParameter/
- resource: {name: email, resourceType: SearchParameter}
fullUrl: https://example.aidbox.app/SearchParameter/
- resource: {name: organization, resourceType: SearchParameter}
fullUrl: https://example.aidbox.app/SearchParameter/
- resource: {name: birthdate, resourceType: SearchParameter}
fullUrl: https://example.aidbox.app/SearchParameter/
- resource: {name: address-country, resourceType: SearchParameter}
fullUrl: https://example.aidbox.app/SearchParameter/
- resource: {name: phone, resourceType: SearchParameter}
fullUrl: https://example.aidbox.app/SearchParameter/
- resource: {name: address-postalcode, resourceType: SearchParameter}
fullUrl: https://example.aidbox.app/SearchParameter/
total: 25
link:
- {relation: first, url: '/SearchParameter?resource=Patient&_elements=name&_page=1'}

With this command above, we can get a list of all search parameters for resourceType Patient (given, address-state, etc.)

Modifiers

We also can do more complex search requests through modifiers that depend on search field type.

Each search parameter value can be one of the following types:

Type

Description

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.

uri

A search parameter that searches on a URI (RFC 3986).

Depending on the value type, different modifiers can be applied.

Common

  • :missing

GET /Entity?description:missing=true

For gender:missing=true, server will return all resources that don't have a value for the gender parameter.

Strings

  • :exact — no partial matches, case sensitive;

  • :contains — case insensitive, partial match at start or end.

Default behavior is case insensitive, partial match at start.

GET /Patient?name:exact=Alex

Token

Reference

Reference describes the relationship between resources. Following options are available for filtering by reference:

Сoded element or identifier

GET /Patient?gender=female
[parameter]=[id]
[parameter]=[type]/[id]

For example, let's find all encounters related to a specified patient:

GET /Encounter?subject=patientid
GET /Encounter?subject=Patient/patientid

Prefixes

For Numbers, Dates and Quantities (will be supported), we can use the following conditionals in search:

  • eq - equal (default)

  • ne - non-equal

  • lt - less than

  • le - less or equal

  • gt - greater than

  • ge - greater or equal

GET /Patient?birthdate=gt1986-04-28

Also at your disposal full-text-search by resources. It presents with _text - search by narrative and _content - search by remaining resource content.

GET /Patient?_text=Foo
GET /Patient?_content=bar

Search results can be sort by rank with _score search-parameter value. More relevant results will be on top but reversed order also supported through - prefix.

GET /Patient?_content=baz&_sort=-_score

Expressions

Full-text search requests supports grouping and logical operations

GET /Patient?_content=(NOT bar OR baz) AND foo

If you wanna search by the phrase - just quote it

GET /Patient?_content="Mad Max"

Full-text search - a difficult query for the system. To improve performance you can omit the number of entries in the results - use _total=none. More information in _total ( _countMethod ).

Chained Parameters

_has

Dot parameters extension

GET /Patient?.name.0.given=Nikolai

_sort

We can define order in result bundle by selected parameters.

For a more accurate search, we can filter by nested fields of related entities. Reference parameters may be "chained" through .

Obtain all encounters with patients (subject — link to the patient) with name Alex:

GET /Encounter?subject:Patient.name=Alex

You can use several chained parameters by base resource:

GET /Encounter?part-of:Encounter._id=enc1&subject:Patient._id=patient1
GET /Organization?_sort=name

"Reversed chaining" is selection of resources based on the properties of resources that refer to them.

Obtain patient resources where encounter has id = enc1 and refer to the patient through subject field:

GET /Patient?_has:Encounter:subject:_id=enc1

_include & _revinclude

We have an ability to include linked entities into result. For example, we want to get all encounters and patients related to them. Structure of the request will be: _include=<reference search parameter> or _include=<Resource>:<reference search parameter>

GET /Encounter?_include=subject
GET /Encounter?_include=Encounter:subject

Or for specific id:

GET /Encounter?_id=enc1&_include=Encounter:subject

Reverse include is specified as a _revinclude

GET /Patient?_id=patient1&_revinclude=Encounter:subject

We have additional modifier (for _include and _revinclude) :logical for search by identifier:

GET /Patient?_id=patient1&_revinclude:logical=Encounter:subject

Ascending order is used by default but we can change this behavior. To sort by descending order, add- before a parameter or specify :asc/:desc after search parameter.

We have an access to attributes of a resource through .

GET /Organization?_sort=-name

It is better described by resulting SQL:

SELECT "patient".*
FROM "patient"
WHERE ("patient".resource#>>'{name,0,given}'in ('Nikolai'));
GET /Organization?_sort:desc=name

As we know, not all attributes can be used as search parameters of a resource but in _sort we have an ability to use them via . notation.

For example, with the following request we will receive an error:

Request
Response
GET /Encounter?_sort=-id
# Status: 500
resourceType: OperationOutcome
...
No search parameter for Encounter.id

We can avoid it with such type of request:

Request
Response
GET /Encounter?_sort=-.id
# Status 200
resourceType: Bundle
entry:
...

Also, we can use several fields for sorting, for this we need to add them through , . Priority will be determined from left to right.

GET /Encounter?_sort=status,-.id

In the example above, we search for all encounters and sort them by the status parameter in cases of equality, the sorting will occur by the id field in the reverse order.

_total ( _countMethod )

By default, for all search requests Aidbox returns total number in result which represents how many resources matched the criteria. But to do this, we run second query for count which takes some additional CPU time. To get a response faster, especially on big amounts of data, you can change this behavior using the _total parameter. The _total parameter can have following values:

  • none - do not run count query

  • estimated - roughly estimate number of results

  • accurate - run accurate count

Paging

Search results can contain many records, for more convenient work we can use pagination. Available parameters are: _count — total records on the page (default value — 100), page — specific page, output Bundle includes link section with first, self, next, previous, and last page constructed URLs.

Request
Response
GET /Patient?_count=10&page=3
resourceType: Bundle
type: searchset
params:
- {type: count, value: 10}
- {type: page, value: 3}
query-sql: ['SELECT "patient".* FROM "patient" LIMIT ? OFFSET ?', 10, 20]
query-time: 9
entry:
- resource:
...
total: 206
link:
- {relation: first, url: '/Patient?_count=10&page=1'}
- {relation: self, url: '/Patient?_count=10&page=3'}
- {relation: next, url: '/Patient?_count=10&page=4'}
- {relation: previous, url: '/Patient?_count=10&page=2'}
- {relation: last, url: '/Patient?_count=10&page=21'}

Want to know more about Aidbox, FHIR, and search? Join our community chat (#aidbox channel).