# Understanding FHIR search

If there were a popularity contest among all available FHIR interactions and operations, the clear winner would be a `search` interaction. [Learn the difference between interactions and operations](https://docs.redoxengine.com/basics/redox-fhir-api/fhir-glossary/#interaction-v-operation). 

In other words, `search` is the most widely supported and versatile type of interaction, meaning that you can search for most resources.

> **Key takeaways**
>
> - <u>**FHIR search**</u> is the most common interaction for FHIR queries.
> - Redox uses the `POST` method for searches, which is more secure as it keeps sensitive data out of the URL.
> - FHIR searches are built using query parameters, which can be refined with <u>**prefixes**</u> (e.g., `_gt`, `_le`) or <u>**modifiers**</u> (e.g., `:not`).
> - You can combine parameters using <u>**chained parameters**</u> (e.g., `subject.name`) or composite parameters (e.g., `participant.name-physical-type=WesternHealth$si`).
> - Search results can be controlled with <u>**result parameters**</u>. Results are returned as a FHIR <u>**bundle**</u>, and large result sets are paginated.

## POST versus GET method

Redox supports the POST method for searching. We use POST because it allows for encoded search parameters in the request body instead of the search URL (like a GET method uses).

HL7 recommends the POST method because it mitigates the risk of leaking confidential data, like PHI, in the request’s URL.

## Search parameters

When you initiate a FHIR query, you can narrow down possible results with <u>**search parameters**</u>. This helps you find the specific data you’re looking for. 

### Support for search parameters

Some search parameters can be easily applied to all FHIR resources, like this one: 

| **Search parameter** | **Notes** |
| --- | --- |
| `_id` | The logical ID of the resource, which can be used when specifying the resource type. |

Other search parameters might be more resource-specific. However, Redox passes any search parameters you include for any FHIR query.

> **Supported search parameters for different sites**
>
> [Read what HL7 says about FHIR search](https://www.hl7.org/fhir/search.html). In this article, we dive into common parameters for `search` interactions. 
>
> However, you should expect variation between sites as to what they require for FHIR searches. Work with your connection to find out which search parameters they require or support for a successful search.

### Refining search parameters

One way to hone your search is to use relevant <u>**prefixes**</u> or <u>**modifiers**</u> on your search parameters. 

#### Prefixes

Redox supports some <u>**prefixes**</u> for ordered search parameters. You can use these to locate resources with (or without) values containing specific numbers, dates, or quantities. For example, you might want to search for an `Appointment` resource with a date range between January 1 and February 1.

| **Search parameter** | **Notes** |
| --- | --- |
| `_gt` | Greater than the provided value. |
| `_ge` | Greater than or equal to the provided value. |
| `_lt` | Less than the provided value. |
| `_le` | Less than or equal to the provided value. |
| `_ne` | Not equal to the provided value. |

#### Modifiers

Redox supports some <u>**modifiers**</u> for tokens (i.e., strings, coding, codeableConcept, identifier, uri), which are suffixes for the parameters. You can use these to locate resources with (or without) specific values. For example, you might want to search for an `Appointment` resource that doesn’t have a pending status.

| **Search parameter** | **Notes** |
| --- | --- |
| `not` | Returns all resources that don’t have a matching item. If you search for a resource with the example above, you’d use `status:not=pending` as a modifier. You receive back any resources with unmatching or unpopulated `status` fields. |
| `missing` | Set this to `true` or `false` to return resources that might or might not have this parameter. If `true`, you want a resource that doesn’t have the parameter; if `false`, you want a resource with this parameter populated. |

### Combining search parameters

You can also combine parameters to use <u>**chained**</u> or <u>**composite parameters**</u>.

<details>
<summary>Chained parameters</summary>

Redox supports some <u>**chained parameters**</u>, which are multiple reference parameters appended with a period and the name of the next parameter. For example, you could use `patient.identifier` together instead of `patient` and `identifier` separately. 

Chained parameters allow you to search for a specific resource type with a parameter used in a referenced resource (e.g., `subject.name` for searching for a `DiagnosticReport` resource, which typically includes a reference to the `Patient` resource for the name).

![Chained parameters](https://images.ctfassets.net/cl3wt5ehhnlv/1LOpdRnBqoZfATq8V5O8cY/bf0ac3af7d7b21f0a9fa33f3b31bca09/FHIR-search-chained-parameters.png)

*Chained parameters*

Not all parameters support chaining. The `identifier` parameter can usually be chained while others might be chainable on a case-by-case basis. [Browse our API reference](https://docs.redoxengine.com/api-reference/fhir-api-reference) to see which chained parameters are supported for a given resource type.

</details>

<details>
<summary>Composite parameters</summary>

Redox supports a limited set of <u>**composite search parameters**</u>, which are specially-defined parameters that allow you to combine multiple values together. They’re mostly used with parameter chaining to locate multiple values within a resource.

Let’s say you want to search for `Appointment` resources. An `Appointment` resource might have one or more references to participants.

![Appointment resources to search](https://images.ctfassets.net/cl3wt5ehhnlv/4E9IONLAzK3z1e2FMINM5g/011ada3193d907e4adb827f03022c790/FHIR-search-appointment-resource-examples.png)

*Appointment resources to search*

You might try searching with these chained parameters: 

- `participant.name=WesternHealth` 
- `participant.physical-type=si` (`si` stands for site). 

You’d get back multiple matches because a search with chained parameters can return results that match either parameter.

![Example 1: Chained parameter search](https://images.ctfassets.net/cl3wt5ehhnlv/OvZNJh5XYVaz1RjujtJSd/fe6e46ff486fda98bdaffa20b8452cff/FHIR-search-chained-parameters-example.png)

*Example 1: Chained parameter search*

But this kind of search could return false positives if one of those parameters matches a location. To avoid this problem, you can use these composite parameters (when available) to make sure that both the name and physical type reference the same chained location: 

- `participant.name-physical-type=WesternHealth$si`

With this composite parameter search, matches would be anything where both of those are true.

![Example 2: Composite parameter search](https://images.ctfassets.net/cl3wt5ehhnlv/3SABCLPsJuUX9Xqw4CDSTZ/8a4a5c77d84d2064d0b68eab2fc89f49/FHIR-search-composite-parameter-example.png)

*Example 2: Composite parameter search*

</details>

### Managing search results

To control how matching results are returned, you can use the following parameters: 

| **Search parameter** | **Notes** |
| --- | --- |
| `_sort` | Sorts results by the specified parameter. For example, you can sort results by date or status. |
| `_elements` | Specifies which elements of a given resource to return to hone in on particular data. This is a comma-separated list (e.g., `Patient_elements=identifier,active,link`). |
| `_include` | Includes any resources that are referenced in the resource identified by the search. Including referenced resources in the response bundle means you don’t have to repeatedly retrieve related resources. |
| `_revinclude` | Includes any resources that reference the resource identified by the search. This is the reverse of `_include`. |
| `_count` | Specifies the maximum number of results to return. Note that for <u>**data on demand**</u>, the maximum count is 1000. |

## What to expect in a search response

When the search parameter(s) match a path found in one or more resources, those resources are returned in a <u>**bundle**</u>. The search criteria defined in the query parameters might match one element or many elements in multiple places, as well as derived values. 

Whenever there’s matching content in any path, the whole resource is returned. You might need to examine the resource to determine which path contains the match.

An empty result (i.e., a bundle with zero entries) means that there weren’t any resources that matched the search criteria. 

If there’s an error of any kind, you receive an HTTP status code (`4XX` or `5XX`). Then the response body is an <u>OperationOutcome</u> resource with an error description.

> **Error codes**
>
> Since Redox passes any search parameters included in your query, any errors you receive about search parameters are from the destination system. Work with your connection to understand which search parameters they support or expect.

### Pagination links

Some FHIR searches find more results than should reasonably be returned at one time. To avoid lengthy responses, FHIR relies on <u>**pagination**</u>, which groups search results into pages. [Learn more about FHIR pagination](https://hl7.org/fhir/http.html#paging). 

The query response contains a `link` array with links to pages that can be fetched using a `GET` or `POST` request against that URL. You can't use additional parameters with a pagination query. 

> **Expired pagination links**
>
> Pagination links expire after 30 minutes. If you attempt to use an expired pagination link, a `404` is returned. If this happens, you’ll need to initiate a new search.

You can see how FHIR pagination links resolve to Redox-centric links in <u>**log inspector**</u>. [Learn about FHIR pagination resolvers](https://docs.redoxengine.com/permalink/Wxms74JvgjSCtaPnJdNFD/#fhir-pagination-resolvers).
