FHIR Chat · Server supporting _contained searches · implementers

Stream: implementers

Topic: Server supporting _contained searches


view this post on Zulip Rik Smithies (Mar 09 2020 at 12:09):

Do any servers support this, and how would the capability statement declare it?
test.fhir.org/r4 appears to ignore _contained, unless I am using it wrongly (there seems no example usage in the spec)
http://test.fhir.org/r4/Provenance?_contained=true&patient.name=rik
finds the same resource, whether or not I use _contained=true (and the self link strips it).

view this post on Zulip Rik Smithies (Mar 12 2020 at 12:13):

So, maybe no servers implement searching into contained resources

view this post on Zulip Grahame Grieve (Mar 12 2020 at 12:30):

mine does

view this post on Zulip Rik Smithies (Mar 12 2020 at 12:43):

ah thanks, good to know. When I tested it as above links it did not seem to look at the _contained parameter, and the self link didn't echo it back, implying it is not supported. Is the URL above correctly formatted?

view this post on Zulip Rik Smithies (Nov 05 2020 at 11:43):

http://test.fhir.org/r4/ didn't work when I tried it and isn't available for testing currently. Do any other servers support "_contained"? @James Agnew @Michael Hansen @Paul Church

view this post on Zulip Paul Church (Nov 05 2020 at 15:59):

No for Google, and no for Microsoft based on their docs. Not sure if HAPI supports it but it's not listed in their search docs so I'm guessing no.

view this post on Zulip Rik Smithies (Nov 05 2020 at 16:28):

Thanks Paul. It's strange that no one supports what seems a fairly important feature and one for which there is no workaround possible.

view this post on Zulip Paul Church (Nov 05 2020 at 16:34):

Searching inside contained resources is technically tricky. I have never heard of anyone needing this feature.

view this post on Zulip Rik Smithies (Nov 05 2020 at 16:36):

Well let me be the first ;-)
If you need contained resources - and people do seem to - it doesn't seem unreasonable to be able to search them.

view this post on Zulip Rik Smithies (Nov 05 2020 at 16:38):

It seems that this basically breaks contained resources.

view this post on Zulip Paul Church (Nov 05 2020 at 17:13):

I do see some use of contained resources, but not searching on them. Because the contained resource is generally a stub or incomplete, it lacks a lot of the things one would normally search for. What's an example of a search that you need to do?

view this post on Zulip Rik Smithies (Nov 05 2020 at 17:23):

Contained is not only for stubs as such, it is also used when there is no desire to make a whole endpoint for a resource type,

  • there is no independent life cycle - but you still want to use that resource.

Hence you may have a full Medication resource contained in a MedicationRequest. Or a Substance in a Medication. And you would want to be able to search on the codes at least. But basically the search params of that resource type. There are examples of both of those in the build, so it's not completely esoteric.

view this post on Zulip Paul Church (Nov 05 2020 at 17:26):

But the general purpose fhir servers have an endpoint for every resource type. So our best practices are to split them out into normal resources.

view this post on Zulip Josh Mandel (Nov 05 2020 at 17:27):

The bullet item in this your message @Rik Smithies -- is this written somewhere in the FHIR spec, or supported by what you see there? The examples in http://build.fhir.org/search.html#containedType are (I'm assuming!) intended to represent a case where the medication has no identifying information other than a code.

view this post on Zulip Paul Church (Nov 05 2020 at 17:28):

Idle speculation, I wonder if we can replace a lot of use cases for stub contained resources with identifier references.

view this post on Zulip Josh Mandel (Nov 05 2020 at 17:28):

"No desire to make a whole endpoint" is hard for me to interpret in terms of technical requirements/constraints/rationale, and introduces questions

view this post on Zulip Rik Smithies (Nov 05 2020 at 17:31):

If you don't need to let people read or write them independently, then no endpoint is needed - less to bother with.

view this post on Zulip Paul Church (Nov 05 2020 at 17:33):

The Google implementation has one API endpoint called GetResource, it handles every DSTU2, STU3, and R4 resource type. The idea of separate API endpoints is not how we think about the world.

view this post on Zulip Rik Smithies (Nov 05 2020 at 17:34):

@Paul But where would the identifier reference point to? We want the resource to be embedded and not need its own endpoint, and still to exist in FHIR. An identifier reference is mainly for things that cannot be referenced by a FHIR url.

view this post on Zulip Rik Smithies (Nov 05 2020 at 17:35):

What I mean is if you only ever use Substance contained in Medication, then you need /myserver/Medication, but you don't need /myserver/Substance "endpoint".

view this post on Zulip Paul Church (Nov 05 2020 at 17:36):

It wouldn't point anywhere, in the case where the identifier is the only thing the server knows about the entity. I agree that if you know more about the resource, then this idea does not apply.

view this post on Zulip Rik Smithies (Nov 05 2020 at 17:37):

yes if you only have an identifier, then you don't need contained at all. But that is a different issue.

view this post on Zulip Rik Smithies (Nov 05 2020 at 17:54):

@Josh Mandel it wasn't meant to emphasised as a bullet but zulip intervened :-) It's not a quote.

But it's just a truism about contained resources. They don't have a lifecycle of their own.

And there are examples of this e.g. http://hl7.org/fhir/medicationadministration0302.xml.html

If you only use that resource type as contained (which I would imagine is common, if you use it as contained at all), then you don't need the machinery of a restful endpoint for that resource type.

You don't need people to write one resource then reference it from the other, or use a transaction. They just only ever use it as if it is an inline datatype.

I'm not suggesting some sort of parallel API endpoint. Only that an implementation may want to not support that resource as an endpoint, but still use it contained. I want to use Task within a resource, to indicate a change request for it. I won't ever use that Task un-contained, so it doesn't need a /Task endpoint.

view this post on Zulip Lloyd McKenzie (Nov 05 2020 at 19:15):

Normally you'd use chaining for that. You wouldn't need _contained

view this post on Zulip Vassil Peytchev (Nov 05 2020 at 19:26):

I want to use Task within a resource, to indicate a change request for it.

Oh my... Is this really a good idea?

In general, I think the guidance that contained resources should not be used to "package" things together is very important. In this case that one side doesn't want to expose an endpoint for Task, maybe they can receive a notification of a Task existing on the requester side and act on it?

In the case of prescriptions, I would rather MedicationRequest have a reference to Substance (where the compound medication is described) in addition to code or a Medication resource. Having contained resources almost mandated for certain uses seems odd.

view this post on Zulip Jean Duteau (Nov 05 2020 at 19:28):

Vassil Peytchev said:

In the case of prescriptions, I would rather MedicationRequest have a reference to Substance (where the compound medication is described) in addition to code or a Medication resource. Having contained resources almost mandated for certain uses seems odd.

No, Medication is where the compound medication is described. And the MedRequest/Dispense/Admin/Statement does have a reference to a Medication resource (CodeableReference). I'm just pointing out that implementers are containing the Medication resource rather than creating them separately.

view this post on Zulip Lloyd McKenzie (Nov 05 2020 at 19:33):

Containing Medication is fine. Containing 'Task' is more problematic. It'd be pretty unusual for Task to not have an independent identity. "I don't want to maintain an endpoint" isn't a justification for using 'contained'.

view this post on Zulip Vassil Peytchev (Nov 05 2020 at 19:50):

No, Medication is where the compound medication is described. And the MedRequest/Dispense/Admin/Statement does have a reference to a Medication resource (CodeableReference). I'm just pointing out that implementers are containing the Medication resource rather than creating them separately.

I was trying to point out that the requirement to have a Medication resource to describe compound medications is used as the reasoning behind containing Medication within MedRequest (I assume because there is no single record of the compund medication to be exposed as Medication resource?). If we had a substance backbone element within MedRequest that contained references to or codes of Ingredients to describe the compound medication, there would be no need to contain a Medication resource.

With the addition of the new MedicinalProduct-related resources, think we need to revise the way medications are handled, and hopefully simplify some of the things that seem to get way too complicated.

view this post on Zulip Rik Smithies (Nov 05 2020 at 20:11):

@Vassil Peytchev yes sometimes a backbone would be good, but sometimes you want the same structure as a resource. If something wants to act like a backbone sometimes and wants to act like a resource at others, that is what contained can do.

view this post on Zulip Rik Smithies (Nov 05 2020 at 20:24):

But if you can't search on it the use is limited

view this post on Zulip Rik Smithies (Nov 05 2020 at 21:28):

Excepting any other uses (or misuses), if Medication is going to be contained I can imagine that people will want to be able to search on it.

view this post on Zulip Vassil Peytchev (Nov 05 2020 at 21:35):

I think Lloyd's point was that contained or not, you can use chaining - did I misunderstand?

view this post on Zulip Gino Canessa (Nov 05 2020 at 21:38):

Just as an aside - this sounds like it would be a lot of work to implement in a performant way.

If the contained resource is an element attached to its parent, the fields will not have been indexed for searching (and even things like full text index don't help for searches on date ranges, etc.).

On the other hand, you cannot assume that contained fragments can be inserted into any normal tables directly. At the very least, you'll need to modify any references/ids/etc. to restrict them to that particular bundle and make sure all the references link back up.

view this post on Zulip Paul Church (Nov 05 2020 at 21:40):

I do not expect that a chained search can navigate into a contained resource. Is that something that other implementations support?

view this post on Zulip Vassil Peytchev (Nov 05 2020 at 21:47):

I probably misunderstood...

view this post on Zulip Lloyd McKenzie (Nov 05 2020 at 22:41):

A chained search can absolutely navigate into a contained resource

view this post on Zulip Lloyd McKenzie (Nov 05 2020 at 22:42):

That's how they're typically accessed when searching. And that's certainly something supported by HAPI and Grahame's server

view this post on Zulip Lloyd McKenzie (Nov 05 2020 at 22:42):

The notion of using _contained was very late to the game and isn't widely supported

view this post on Zulip Rik Smithies (Nov 05 2020 at 22:49):

does _contained only affect the output? I thought it affected the search itself?

view this post on Zulip Lloyd McKenzie (Nov 05 2020 at 23:06):

_contained changes what's being searched.

view this post on Zulip Rik Smithies (Nov 05 2020 at 23:19):

right, yes. But I now see that you can search into a contained Y in an X, using e.g. X?Y.code
That doesn't need _contained.

view this post on Zulip Rik Smithies (Nov 05 2020 at 23:20):

As long as you know what is contained in what, that is enough.

view this post on Zulip Lloyd McKenzie (Nov 06 2020 at 00:04):

When you're doing chaining, you don't care if it's contained or not. MedicationRequest?medication.code=foo works whether the medication is contained or not.

view this post on Zulip Paul Church (Nov 06 2020 at 00:08):

How is that implemented? Do the contained resources have their own database rows that can be joined?

view this post on Zulip Lloyd McKenzie (Nov 06 2020 at 00:16):

@Grahame Grieve @James Agnew

view this post on Zulip Josh Mandel (Nov 06 2020 at 02:48):

I think that's the usual approach (it's what the SMART server did, back in the day)

view this post on Zulip James Agnew (Nov 06 2020 at 03:05):

HAPI certainly does not support this, for all of the same reasons listed above: tricky to implement in a performant way, and at least personally most use cases I've seen where someone has wanted to do it have ultimately been because the person was trying to misuse contained resources (and therefore a workaround existed to just use a non-contained resource, or an identifier reference, or an alternative to the reference (e.g. reasonCode instead of reasonReference).

OTOH I've seen a handful of people work around this limitation by creating a custom search parameter with a path that explicitly dives into the contained resource. Oddly enough one such instance was for compound medications like Vassil described above.

view this post on Zulip Paul Church (Nov 06 2020 at 03:47):

Does HAPI support chaining into a contained resource though?

view this post on Zulip Paul Church (Nov 06 2020 at 04:44):

Also, does _content search inside contained resources? Does _text search the narrative of contained resources, if they have one?

view this post on Zulip Paul Church (Nov 06 2020 at 04:58):

Now it's midnight and you've got me writing a design doc for how this could be implemented.

view this post on Zulip Rik Smithies (Nov 06 2020 at 13:09):

Presumably this would also work with reverse chaining? e.g. to search into a contained Provenance (which refers to the containing resource, not the other way around).

view this post on Zulip Lloyd McKenzie (Nov 06 2020 at 22:19):

@James Agnew HAPI doesn't support _contained (which I'm fine with) or HAPI doesn't support chaining into contained resources (which is a pretty serious limitation because contained practitioners inside PractitionerRole, contained Medication inside various resources and lots of other scenarios like that will be pretty common. There are lots of valid reasons for contained resources and you certainly don't want to drop to identifier references which are definitely non-searchable.

view this post on Zulip James Agnew (Nov 09 2020 at 00:06):

The chaining use case is currently only achievable using custom search parameters with a FHIRPath that dives right into the contained resource for the indexed content.

view this post on Zulip Paul Church (Nov 09 2020 at 16:02):

It seems like there's a real disconnect between Lloyd/Rik saying this is important and all of the implementers on this thread saying they're not doing it. Is there implementation experience on the EHR side?

view this post on Zulip Michele Mottini (Nov 09 2020 at 16:23):

Most EHR do not have chained search at all

view this post on Zulip Jens Villadsen (Nov 09 2020 at 17:15):

Most EHRs are arcane monoliths from the 80'ies or 90'ies which was based and build on different grounds of such search capabilties

view this post on Zulip Rik Smithies (Nov 09 2020 at 18:58):

FHIR isn't only for facades onto big iron EHRs. When used that way, FHIRs capabilities are always likely to be a superset. Why bother with chaining at all?

But in general FHIR should provide a consistent feature set. Contained resources without search are not much use. And they were invented for good reasons.

view this post on Zulip Paul Church (Nov 09 2020 at 19:19):

Yes, I agree with that but the useful ideas with good reasons need to be tested through implementation experience! The search spec has made it all the way to normative and yet we're having this conversation about whether anyone actually supports _contained or chaining into contained resources.

view this post on Zulip James Agnew (Nov 09 2020 at 19:30):

Completely agree with Paul on this.

I still don't understand the use cases for needing this (with 'this' meaning searches reaching into contained resources).

The only place I've personally seen it used for was the compound medications one, and if I'm honest, that just felt like it was working around a weakness in the resource models (i.e. clearly it was important to the implementer to be able to track ratios of products in an IV solution as an atomic unit-- so why don't we provide a way to do this that doesn't require contained resources?)

Are the other use cases similar?

view this post on Zulip Lloyd McKenzie (Nov 09 2020 at 19:33):

I've seen 'contained' resource in lots of cases. Contained 'Provenance' where the Provenance isn't maintained independently. Contained Questionnaire within QuestionnaireResponse when doing adaptive questionnaires. Contained Practitioners when the source data captures the provider as part of the record rather than as a stand-alone registry entry.

view this post on Zulip Lloyd McKenzie (Nov 09 2020 at 19:34):

Contained is going to be pretty common - and being able to chain into contained resources is also going to matter

view this post on Zulip Vassil Peytchev (Nov 09 2020 at 19:56):

I've seen 'contained' resource in lots of cases.

Seen in specifications, or seen in actual use?

view this post on Zulip Lloyd McKenzie (Nov 09 2020 at 20:02):

Actual use

view this post on Zulip Jean Duteau (Nov 09 2020 at 20:17):

I'm involved in a number of implementations that are using contained resources. One healthcare FHIR server uses contained resources for many of the reasons that Lloyd suggested. Medications are contained because they need to provide the information in that resource but they aren't maintaining them independently. Practitioners are contained because they have practitioner information but they aren't serving those up as independent resources.

view this post on Zulip Lloyd McKenzie (Nov 09 2020 at 20:23):

Lots of legacy repositories will have to use contained because of how their data is organized. Even those with a strictly FHIR-based repository will still have to use contained where the resource doesn't have independent identity (e.g. the adaptive forms approach defined in Argonaut and SDC)

view this post on Zulip Rik Smithies (Nov 09 2020 at 20:39):

We use contained Provenance - and cannot find a way to search. It needs reverse chaining.
(I was wrong about Task, we use that but it is not contained...).

view this post on Zulip Lloyd McKenzie (Nov 09 2020 at 20:46):

If you have a contained provenance, it would be unusual to search on it. To do that you would need _contained

view this post on Zulip Rik Smithies (Nov 09 2020 at 20:58):

Well I guess that depends if you want to search on Provenance itself or to find containing resources that have some embedded Provenance aspect. The use case of Provenance here is to hold the actual updated date of the (legacy) data, and not the timestamp of the resource. Then search on it.

view this post on Zulip Paul Church (Nov 09 2020 at 21:16):

@Lloyd McKenzie but have you seen _contained search or chaining into contained in lots of cases? It sounds to me like out of the production implementations represented here, nobody supports them, nobody has stated plans to support them, and nobody is quite sure if they're technically feasible at all.

view this post on Zulip Lloyd McKenzie (Nov 09 2020 at 21:27):

I have never seen _contained. That's pretty esoteric. DaVinci and SDC both require searching by the URL of the contained Questionnaire to retrieve completed questionnaires for instruments like promise. Searching by dispenses by medication or lot number would also generally require hitting contained resources. (There's zero chance of them being stand-alone resources, particularly in community pharmacy and even in inpatient, it'd be unusual.)

view this post on Zulip Paul Church (Nov 11 2020 at 17:38):

If anyone wants to try implementing chaining into contained resources I would like to highlight the case where Patient/1 refers to a contained PractitionerRole #pr, and that PractitionerRole refers to a contained Organization #o (which is contained in the Patient, since contained resources aren't nested) with a name of X.

There are two interesting cases that should both return Patient/1:

  1. PractitionerRole?organization.name=X&_contained=true
  2. Patient?general-practitioner.organization.name=X

view this post on Zulip Grahame Grieve (Nov 12 2020 at 10:10):

catching up with this... I absolutely support chaining into contained resources. Contained resources are a row in my database just like any other resources, with a key to the container resource (so I can decide whether I want to see them or not). I think I don't implement _contained fully but chained search into contained resources is important


Last updated: Apr 12 2022 at 19:14 UTC