hl7-fhirhapi-fhir

How to search in HAPI FHIR using reverse chaining and AND operations?


I have a list of Schedules. Each Schedule have many related Slots. Each Slot has an specific date and status, which can be free or busy.

I want to search all Schedule that have free Slots in a specific date. E.g, I want to get all Schedules with free slots on 2023-12-06. Is it possible to do it with only one query?

At this moment I've already got: /Schedule?_has:Slot:schedule:start=2023-12-06&_has:Slot:schedule:status=free

But this search has a major flaw: it get Schedules with Slots at 2023-12-06 OR free Slots, and this is not what I want.

How could I solve this problem?


Solution

  • Yes, that is the expected behavior of Reverse Chaining - specifically that each _has operator is evaluated independently. You do have a few options:

    1. filter the results client-side

    Since the results are over-broad, the client is not missing data. The client can filter through the results and reduce down to the desired set.

    1. define a custom composite search parameter

    You can define a new SearchParameter for the Slot resource. If the search parameter is a composite type with the parts start and status, the evaluation will be joined together. I believe you will need to issue a re-index on HAPI, but it is good about that. For example, if the composite parameter was coded as start-status, your search could look like: Schedule?_has:Slot:schedule:start-status=2023-12-06$free

    1. Use the _filter parameter

    Using the _filter parameter gives more flexibility in general, at the cost of more complex query-building. I believe HAPI supports _filter out-of-the-box, but I am not completely sure. Based on your earlier query, I think a filter-based one would look something like: Schedule?_filter=(_has:Slot:schedule:start eq 2023-12-06 and _has:Slot:schedule:status eq free)

    1. Define a Named Query

    More complex but even more flexible, you can define a Named Query to get the search results you want. Similar to defining a search parameter, except that you define an operation (using OperationDefinition) and then search using the name of the operation.

    Hope this helps, cheers! -Gino