Skip to content
Jason Walonoski edited this page Apr 21, 2020 · 25 revisions

Search Using the Models

Associate the client with the model:

FHIR::Model.client = client

The FHIR models can now be used to directly interact with a FHIR server.

# search patients
result = FHIR::Patient.search(given: 'John', family: 'Doe')
# result is a FHIR::Bundle
bundle.each do |resource|
  puts resource.name[0].text
end

If the search is successful, you can use the FHIR::Bundle.each method to iterate over the results (even if they are paginated). See automatically paginating search results or manually paginating search results for more information.

Search Using the Client

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

Automatically Paginating Search Results

Assuming read permissions exist on the resource type, a search result will be returned as a FHIR::Bundle and the resulting entries can be iterated over using the FHIR::Bundle method each.

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 which can be paginated. The FHIR::Bundle instance method each illustrated above, not only iterates through the Bundle entry array, but it will also fetch the next page of results assuming the Bundle contains a "next" link.

Manually Paginating Search Results

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 method or the FHIR::Client.next_page 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)

Searching with Parameters

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
    }
  }
}

Search By Parameter

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

Search by Date/Time

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}"] }})

Search by Reference

# 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}" } })

Search By Compartment

# 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

Search By URL Encoded POST

# 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

Searching with AND, OR, and Composite Values

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' } })
Clone this wiki locally