5.4.1FHIR Search: Custom Search Parameters

 

The FHIR specification includes a rich set of default Search Parameters. For example, see the Patient Resource Search Parameters.

However, the list of search parameters specified in the core FHIR specification is only the default. You can create your own Search Parameters in Smile CDR in order to index fields and extensions that are not indexed by default. You can also customize how Search Parameters behave, and remove search parameters you do not need.

In FHIR, a Search Parameter is defined using a special resource called SearchParameter. You can customize and update existing SearchParameters (which are automatically inserted into your database the first time the system starts up) and you can add new ones too.

5.4.2An Example Search Parameter

 

What follows is an example of a search parameter on an extension. We'll suppose that in our system we've defined an extension for a given patient's eye colour. Patient resources stored in our database will have the eye colour extension set, and we want to be able to search on this extension, too.

1. Create the Search Parameter

First, define a search parameter and upload it to your server. The following shows the SearchParameter resource. Note the expression value, which is a FHIRPath expression.

{
	"resourceType": "SearchParameter",
	"title": "Eye Colour",
	"base": [ "Patient" ],
	"status": "active",
	"code": "eyecolour",
	"type": "token",
	"expression": "Patient.extension('http://acme.org/eyecolour')",
	"xpathUsage": "normal"
}

2. Upload Some Resources

Let's upload two Patient resources with different eye colours.

{
  "resourceType": "Patient",
  "extension": [
    {
      "url": "http://acme.org/eyecolour",
      "valueCode": "blue"
    }
  ],
  "active": true
}
{
  "resourceType": "Patient",
  "extension": [
    {
      "url": "http://acme.org/eyecolour",
      "valueCode": "green"
    }
  ],
  "active": true
}

3. Search!

Finally, let's try searching: http://example.com:8000/Patient?eyecolour=blue

This produces a search result that contains only the matching resource:

{
  "resourceType": "Bundle",
  "id": "bc89e883-b9f7-4745-8c2f-24bf9277664d",
  "meta": {
    "lastUpdated": "2017-02-07T20:30:05.445-05:00"
  },
  "type": "searchset",
  "total": 1,
  "link": [
    {
      "relation": "self",
      "url": "http://example.com:8000/fhir/context/Patient?eyecolour=blue"
    }
  ],
  "entry": [
    {
      "fullUrl": "http://example.com:8000/fhir/context/Patient/2",
      "resource": {
        "resourceType": "Patient",
        "id": "2",
        "meta": {
          "versionId": "1",
          "lastUpdated": "2017-02-07T20:30:05.317-05:00"
        },
        "extension": [
          {
            "url": "http://acme.org/eyecolour",
            "valueCode": "blue"
          }
        ],
        "active": true
      },
      "search": {
        "mode": "match"
      }
    }
  ]
}

5.4.3Search Parameter Expressions

 

The SearchParameter.expression element determines the exact path within the resource that should be extracted and indexed when a target resource is being stored.

See FHIRPath Expressions for examples.

5.4.4Combo Search Index Parameters

 

HAPI FHIR and Smile CDR define a special type of SearchParameter called a Combo Search Index Parameter that is used to index a combination of parameters together in a single database table. For example, consider the following search: http://localhost:8000/Patient?family=smith&gender=http://hl7.org/fhir/administrative-gender|male&birthdate=2021-01-01

By default, the search above relies on separate index tables to manage the family name, gender, and birthdate parameters. This generally works well, but can lead to performance issues if each of these parameters individually returns a large number of records (as would likely be the case for the family and gender parameters above in a large FHIR repository).

Using a Combo Search Index Parameter avoids unnecessary database joining by combining (denormalizing) all of the above values into a single database table for indexing and searching. Optionally, Smile CDR can also enforce uniqueness for the values of the parameters. See Enforcing Uniqueness below for more information.

5.4.4.1Composite vs Combo Search Index Parameters

Note that Combo Search Index Parameters are a different concept from the FHIR Composite Search Parameter type.

FHIR Composite Search Index Parameters use a single parameter in a REST search URL to express multiple values where the values are closely related within the resource (e.g. the component code and component value within an Observation).

HAPI FHIR / Smile CDR Combo Index Search Parameters use multiple parameters in a REST search URL to express unrelated search parameters that are intended to be used together.

Both of these concepts are defined using a SearchParameter resource with a type of composite, however the latter uses an sp-unique extension to mark it as a combo search parameter.

There are limited number of Search Parameter types that can be used in composite and combo Search Parameters. For more details see Composite and combo search parameter component types.

5.4.4.2Example

The following example shows a sample Non-unique Combo Index Search parameter and it assumes that you have already created the 3 individual SearchParameter resources based on the Patient resource's properties being used here (family, gender and birthdate) :

{
  "resourceType": "SearchParameter",
  "extension": [
    {
      "url": "http://hapifhir.io/fhir/StructureDefinition/sp-unique",
      "valueBoolean": false
    }
  ],
  "status": "active",
  "code": "family-gender-birthdate",
  "base": [
    "Patient"
  ],
  "type": "composite",
  "expression": "Patient",
  "component": [
    {
      "definition": "SearchParameter/individual-family",
      "expression": "Patient"
    },
    {
      "definition": "SearchParameter/individual-gender",
      "expression": "Patient"
    },
    {
      "definition": "SearchParameter/individual-birthdate",
      "expression": "Patient"
    }
  ]
}

5.4.5Enforcing Uniqueness

 
This feature is a Smile CDR / HAPI FHIR extension to the FHIR specification and may not be available on other servers.

This section outlines how to ensure that values are unique within a repository.

5.4.5.1Unique Combo Search Index Parameters

Unique combo search index parameters are special search parameters that are a combination of one or more existing search parameters. These search parameters enforce uniqueness for the combined values matched by the given search parameters across the entire repository.

Consider a repository that stores Encounter resources. These encounters have a subject (the Patient) and a date (the date of the encounter). This combination of parameters may be expressed using a search such as the following URL: https://try.smilecdr.com:8000/baseR4/Encounter?date=2017-07-09&subject=Patient/b765fe0d-34fa-4427-b540-1be4ec4acbda

Now, suppose you wish to enforce a business rule that a given Patient may only have one Encounter per day. A combo search index parameter can be used to enforce this uniqueness by declaring that combinations of the Encounter:date and Encounter:subject search parameters are globally unique.

Unique Combo Search Index Parameters enforce this uniqueness using a unique database index enforced by the RDBMS, so they are consistent even under high concurrency. They are declared using a SearchParameter resource. The following example shows a SearchParameter resource for this case (R4+ syntax shown below):

{
  "resourceType": "SearchParameter",
  "extension": [
    {
      "url": "http://hapifhir.io/fhir/StructureDefinition/sp-unique",
      "valueBoolean": true
    }
  ],
  "status": "active",
  "code": "subject-and-date",
  "base": [
    "Encounter"
  ],
  "type": "composite",
  "expression": "Encounter",
  "component": [
    {
      "definition": "SearchParameter/clinical-patient",
      "expression": "Encounter"
    },
    {
      "definition": "SearchParameter/clinical-date",
      "expression": "Encounter"
    }
  ]
}

The combo search parameter above contains two references to other SearchParameter resources (in this case, Encounter:patient and Encounter:date, which are represented by the IDs SearchParameter/clinical-patient and SearchParameter/clinical-date respectively).

In order to create the composite search parameter, first the existing SearchParameter resources should be looked up to determine their respective IDs. This can be done using a query such as the following example: http://example.com:8000/SearchParameter?base=Encounter&code=date,patient

This returns a result such as the following (most of the content has been removed for readability):

{
  "resourceType": "Bundle",
  "type": "searchset",
  "entry": [
    {
      "resource": {
        "resourceType": "SearchParameter",
        "id": "clinical-patient",
        "code": "patient"
      }
    },
    {
      "resource": {
        "resourceType": "SearchParameter",
        "id": "clinical-date",
        "code": "date"
      }
    }
  ]
}

Note that it is not necessary for the parameter to have more than one component. If a single search parameter should be unique, the composite search parameter may have a single component.

The http://hapifhir.io/fhir/StructureDefinition/sp-unique extension must exist in a search parameter in order for it to be indexed as a unique search parameter, and this extension should have a boolean value of true as shown above.

5.4.5.2Limitations

On partitioned systems, uniqueness is currently enforced globally per database. This means that the same values will not be permitted even on different partitions.

In the case of MegaScale repositories, uniqueness is enforced globally on each MegaScale database. This means that two separate MegaScale databases can have the same unique value exactly once.