-
Notifications
You must be signed in to change notification settings - Fork 61
Searching
Associate the client with the model:
FHIR::Model.client = client
The FHIR models can now be used to directly interact with a FHIR server.
For example, you can use FHIR::Patient
or FHIR::Encounter
or any FHIR
resource class to directly search using the search
method:
# replace FHIR::Model with an actual resource class such as FHIR::Patient or FHIR::MedicationRequest
FHIR::Model.search(parameters)
The FHIR::Model.search
method takes in a hash of search parameters
(strings as keys, and strings or numbers as values), and on a successful query returns a FHIR::Bundle
instance. On error, the search method raises Exceptions that must be handled.
# search patients
bundle = FHIR::Patient.search(given: 'John', family: 'Doe')
# On success, bundle is a FHIR::Bundle, otherwise an exception is thrown
bundle.each do |resource|
puts resource.name[0].text
end
If the search is successful, you can use the FHIR::Bundle#each
instance method to iterate over the results (even if they are paginated). See automatically paginating search results or manually paginating search results for more information.
You can also search using dates, date times, references, and any other legal search parameters
. For example, to search with dates:
# search encounters by date, greater (or after) April 1st 2020
# GET [base]/Encounter?date=gt2020-04-01
bundle = FHIR::Encounter.search(date: 'gt2020-04-01')
See searching by date and time to see the list of modifiers (e.g. gt
is greater than) and other examples.
The remainder of the examples below can be used with FHIR::Model.search
by using the appropriate parameters
shown in each example.
There are several search methods built into the client. The most simple example is the "search" involving no parameters.
client.read_feed(klass, format = nil)
In this case klass
is the class representing the FHIR resource type to search, e.g. FHIR::Patient
or FHIR::Observation
, and format
is one of four options:
FHIR::Formats::ResourceFormat::RESOURCE_XML
FHIR::Formats::ResourceFormat::RESOURCE_JSON
FHIR::Formats::ResourceFormat::RESOURCE_XML_DSTU2
FHIR::Formats::ResourceFormat::RESOURCE_JSON_DSTU2
Examples:
# using the current default format
reply = client.read_feed(FHIR::Patient)
bundle = reply.resource
# overriding the default format to use XML
reply = client.read_feed(FHIR::Observation, FHIR::Formats::ResourceFormat::RESOURCE_XML)
# print the raw XML of the Bundle
puts reply.body
# use the search result bundle (inflated from the raw XML)
bundle = reply.resource
Assuming read permissions exist on the resource type, a search result will be returned as a FHIR::Bundle
instance and the resulting entries can be iterated over using the FHIR::Bundle#each
instance method.
reply = client.read_feed(FHIR::Patient) # fetch Bundle of Patients
bundle = reply.resource
bundle.each do |resource|
puts resource.name[0].text
end
puts reply.code # HTTP 200 (or whatever was returned)
puts reply.body # Raw XML or JSON
Assuming read permissions exist on the resource type, a search result will be returned as a FHIR::Bundle
instance which may be paginated. The FHIR::Bundle#each
instance method, illustrated above, not only iterates through the FHIR::Bundle#entry
array, but it will also fetch the next page of results assuming the Bundle contains a "next" link.
As explained above, using the FHIR::Bundle#each
instance method will iterate and paginate results, but if you want to paginate manually, you can do so using the FHIR::Bundle#next_bundle
instance method or the FHIR::Client#next_page
instance method.
# next_bundle example
reply = client.read_feed(FHIR::Patient) # fetch Bundle of Patients
bundle = reply.resource
another_bundle = bundle.next_bundle
# next_page example
reply = client.read_feed(FHIR::Patient) # fetch Bundle of Patients
bundle = reply.resource
another_reply = client.next_page(reply)
# next_page in a different direction (FOWARD, BACKWARD, FIRST, or LAST)
reply = client.read_feed(FHIR::Patient) # fetch Bundle of Patients
bundle = reply.resource
another_reply = client.next_page(reply, FHIR::Sections::Feed::BACKWARD)
The default search
method has the following signature:
def search(klass, options = {}, format = @default_format)
-
klass
- the FHIR resource class to search, e.g.FHIR::Patient
. -
options
- a Hash of search options described below.
options = {
:resource => klass,
:format => format,
:id => 123, # only use if you are searching by compartment
:search => {
:flag => false, # :flag is optional. Search by POST when true, otherwise GET.
:compartment => 'CompartmentName', # optional searching by compartment
:parameters => {
# list of key/value pairs go here
}
}
}
The name
parameter in the following example can be substituted for any combination of parameters as described in http://hl7.org/fhir/R4/search.html including dates, numbers, chaining, and so forth.
# GET [base]/Patient?name=Peter
reply = client.search(FHIR::Patient, search: { parameters: { name: 'Peter' } })
bundle = reply.resource
patient = bundle.entry.first.resource
FHIR date/dateTime searches are documented at http://hl7.org/fhir/R4/search.html#date.
You may need to use the following notation in your search parameters:
-
eq
- equal -
ne
- not equal -
gt
- greater than -
lt
- less than -
ge
- greater or equal -
le
- less or equal -
sa
- starts after -
eb
- ends before -
ap
- approximately
# DATE /Encounter?date=gt2020-04-01
client.search(FHIR::Encounter, search: { parameters: { date: 'gt2020-04-01' } })
# DATE using Time
t = Time.now
client.search(FHIR::Encounter, search: { parameters: { date: "eq#{t.to_date.to_s}" } })
# DATETIME /Encounter?date=gt2020-04-01T10:00
client.search(FHIR::Encounter, search: { parameters: { date: 'gt2020-04-01T10:00' } })
# DATETIME using Time
t = Time.now
client.search(FHIR::Encounter, search: { parameters: { date: "gt#{t.iso8601}" } })
# DATE BETWEEN START AND STOP
start = '2020-04-01'
stop = '2020-05-01'
client.search(FHIR::Encounter, search: { parameters: { date: ["gt#{start}", "lt#{stop}"] }})
# Get an Encounter
reply = client.search(FHIR::Encounter)
bundle = reply.resource
encounter = bundle.entry.first.resource
# Get all Encounters for this subject
client.search(FHIR::Encounter, search: { parameters: { subject: encounter.subject.reference } })
# Get all Observations for a specific encounter
client.search(FHIR::Observation, search: { parameters: { encounter: "Encounter/#{encounter.id}" } })
Composite value searching is described in http://hl7.org/fhir/R4/search.html#combining
# AND: /Patient?language=FR&language=NL
client.search(FHIR::Patient, search: { parameters: { language: [ 'FR', 'NL' ] } } )
# OR: /Patient?language=FR,NL
client.search(FHIR::Patient, search: { parameters: { language: 'FR,NL' } })
# COMPOSITE: /Group?characteristic-value=gender$mixed
client.search(FHIR::Group, search: { parameters: { 'characteristic-value': 'gender$mixed' } })
# GET [base]/Patient/123/Condition?code:in=http://hspc.org/ValueSet/acute-concerns
reply = client.search(FHIR::Patient, { id: 123,
search: {
compartment: 'Condition',
parameters: { 'code:in': 'http://hspc.org/ValueSet/acute-concerns' }
}})
bundle = reply.resource
# POST [base]/Patient/_search?name=Peter
reply = client.search(FHIR::Patient, search: { flag: true, parameters: { name: 'Peter' } })
bundle = reply.resource
patient = bundle.entry.first.resource
FHIR allows you to search on a server across multiple, or all, resource types. See http://hl7.org/fhir/R4/search.html#_type.
In order to execute one of these searches, you need to use the client.search_all
method.
def search_all(options = {}, format = @default_format)
Example:
# From the spec:
# GET [base]/?_type=Observation,Condition&other params...
results = client.search_all(search: { parameters: { '_type': 'Observation,Condition' } }
- Getting Started
- Configuration
-
Searching
- History
- CRUD
- Transactions
- Validation
-
Operations
$everything
$validate