Stream: terminology
Topic: Extensions vs properties
Brian Postlethwaite (Feb 21 2019 at 10:27):
Wondering what the rationale was to use the property bag in terminology vs using extensions like in rest of fhir.
Lloyd McKenzie (Feb 21 2019 at 15:51):
Properties fall within the 80% for code systems. We also need them to filter valuesets
Brian Postlethwaite (Mar 08 2019 at 03:09):
Just a question on this, does the terminology stuff support extensions (technically yes) but do these then flow through the expansions?
Do if I put an extension on a concept in a code system and this is returned in an expansion on a valueset, should the extensions come too?
(the properties don't as there is no place to put them)
Peter Jordan (Mar 08 2019 at 03:25):
Extending concepts in a Code System is facilitated by Code System Supplements see http://hl7.org/fhir/codesystem.html at 4.8.8; noting the caveat on their use in ValueSet expansions in the 'trial use' box.
Jim Steel (Mar 08 2019 at 04:58):
I don't think supplements help with getting extra information back in an expansion (it can add properties, but they won't/can't come back in an expansion any more than other CodeSystem properties can).
@Michael Lawley was talking about something like a ValueSet/$lookup operation, that might meet some of the needs, in https://chat.fhir.org/#narrow/stream/179202-terminology/topic/ValueSet.2F.24lookup
Brian Postlethwaite (Mar 08 2019 at 10:56):
So, in summary, terminology expansion has no standard extensibility mechanism.
Robert McClure (Mar 08 2019 at 16:20):
You all are much more knowledgable on the technical issues, but @Peter Jordan is exactly correct that code system supplements is intended to allow you to add properties and additional relationships to a code system, they just can not add additional concepts (that is a code system fragment).
It was our intent to be able to specify that an expansion operation use any number of supplements when generating the expand with the expectation that the result would include anything added in the supplement. @Jim Steel you seem to say something different?
As for code system $lookup (or valueset $lookup) - I certainly assume the same behavior. In fact, the whole point of a supplement (or a fragment) is that they can be added to the code system for any operation. @Rob Hausam am I missing something?
Jim Steel (Mar 09 2019 at 01:31):
My point (and my understanding of the original question from @Brian Postlethwaite ) was that the concept elements that come back in a ValueSet from an $expand request cannot currently have properties in them. So regardless of whether the property values are defined in the original CodeSystem or in a supplement, they cannot currently come back in the result of $expand.
Brian Postlethwaite (Mar 09 2019 at 01:37):
Correct, and same with extensions on the concepts in the code system. They don't d
Come back either.
Peter Jordan (Mar 09 2019 at 02:22):
Depends what you mean by 'extensions' in this context (extensions on one of the coded data types?). Supplements that are additional designations (e.g. an alternative language) can be returned in ValueSet expansions. However, as Jim says, properties cannot - whether they are part of the 'core' Code System or supplementary properties; at present, these are only returned by a CodeSystem $lookup operation.
Michael Lawley (Mar 09 2019 at 03:40):
at present, these are only returned by a CodeSystem $lookup operation
And there are a couple of (informal) proposals floating around to either:
1. extend /ValueSet/$expand
so that it can return a concept's properties, or
2. introduce /ValueSet/$lookup
that acts just like /CodeSystem/$lookup
but that takes a valueset as a parameter instead of a code and does a $lookup
on all members of the valueset's expansion
From one perspective, option 1 seems like the most straightforward. However, I have also proposed something like /ValueSet/$translate
to enable (efficient) batch-translation of multiple concepts. So option 2 is really about having a consistent mechanism for performing terminology operations on a set of codes rather than just a single code.
Grahame Grieve (Mar 14 2019 at 07:14):
so there's no simple way to pipe operations because you need some language to transform between first output and second input - and it rapidly gets yucky.
Grahame Grieve (Mar 14 2019 at 07:15):
right now, the only way to do this is
- $expand to get the list. Note that supplements may alter the list if it's specified extensionally based on properties and the supplements provide values for the properties
- N $lookups to get the properties
Grahame Grieve (Mar 14 2019 at 07:15):
this is one of 3 deficiencies in the API that we need to solve. I'd like to pilot a proposal at Montreal on this.
Grahame Grieve (Mar 14 2019 at 07:18):
the other deficiencies:
- a single call that takes any kind of resource and populates all the display values
- dealing with the v2/CDA/openEHR issues (alternative system identifiers)
Rob Hausam (Mar 14 2019 at 12:36):
Are you going to make the proposal for the alternative to $expand --> N $lookups? What do you mean by pilot for this?
Grahame Grieve (Jun 04 2019 at 05:47):
ping on this. Can we talk about this at DevDays?
Rob Hausam (Jun 04 2019 at 11:57):
Sure. Sounds like a good plan.
Paul Lynch (Jun 04 2019 at 15:30):
@Grahame Grieve Coincidentally we are just getting back to focusing on this problem. I won't be at DevDays, unfortunately, but I like the proposal you made last year where you wrote:
"an alternative approach which is more value set centric - and probably better for getting properties, is to add to value set (probably extensions for now) a column : string 0..* for each contains, and a column: {name, uri, type} to the expansion that defines the columns. and some kind of column= parameter in the $expand"
Related to this problem for us, and possibly worth looking at together, is the need for the client to select which properties are searched during an $expand.
Brian Postlethwaite (Jun 04 2019 at 20:59):
Count me in on that dev days discussion
Jim Steel (Jun 04 2019 at 23:44):
I think @Michael Lawley and I would also like to be in that discussion
Grahame Grieve (Jun 10 2019 at 18:18):
pop up at DevDays: Wednesday 11.55 - 12.35: McKinley: Returning extensions in value set expansions
Jim Steel (Jun 12 2019 at 19:05):
@Grahame Grieve You should come, its awesome ;)
Grahame Grieve (Jun 12 2019 at 19:35):
Outcomes:
1. define an ordinal property (can be pre-adopted in <R5)
1a. change the ordinal value extension to only be used in Questionnaire (GF#22698)
2. define a way to put properties in expansions in R5 (match the CodeSystem pattern)
3. define an extension to put properties in expansions in R4 (matching the CodeSystem pattern)
4. define a way for a client to ask for particular properties in expansions : property string 0..* a code or a URI for a property that the client wishes to be returned (or *)
5. define a way for a value set to specify the default returned properties
6. document the use of :in to search by property value
7. define a way for a value set to specify the order if filtered based on properties
Grahame Grieve (Jun 17 2019 at 04:39):
not clear how a value set provides an ordinal. More generally, is there any validity in a value set defining properties for the codes it references....
Grahame Grieve (Jun 17 2019 at 04:40):
we've said that ordinals may be defined in valuesets
Robert McClure (Jun 21 2019 at 14:06):
@Grahame Grieve
Help me track the discussion a bit. Here is how I have always thought of the parts going together:
- Value set CLD identifies concepts for expansion inclusion using
- concept properties or relationship data defined in the base code system, and/or
- concept properties (ordinal or otherwise) or relationship data defined in a code system supplement (that can be crafted by anyone)
- I think we have allowed, but do not understand how to, define a new value set specific concept property (relations too? - like a new hierarchy?) within the CLD for a specified code. By this I mean enumerate a set of codes in the include and give each of the codes value set specific properties valid only in the context of an expand for this value set.
- Is this what you are discussing?
What we have not clearly defined, or I don't understand, is how to
- specify a concept property only on the results of the expansion membership, ie: associate an ordinal value to only the values in the value set expansion based on being in the expansion
Then, how do you get the content used above to show up in an expansion? Also, we don't have any way that I know of to specify that everyexpansion of a value set would have specific concept properties included in the expand, correct?
Grahame Grieve (Jun 21 2019 at 20:04):
Value set CLD identifies concepts for expansion inclusion
why CLD? why not the request for the expansion itself. The CLD defines what's in the value set, but the system using the value set knows what properties it wants
how to, define a new value set specific concept property (relations too?
yes, that's one of things on my list
is how to specify a concept property only on the results of the expansion membership
That's also on the list above
Grahame Grieve (Jun 21 2019 at 20:04):
how do you get the content used above to show up in an expansion
that's the primary todo - extend expansion to cover that
Robert McClure (Jun 27 2019 at 14:14):
why CLD? why not the request for the expansion itself.
I assume you didn't follow my point. The CLD uses concept identity, properties, relations, etc. to determine expansion concept membership. I think you are questioning what properties, etc. for those concepts that would also be included in the expansion, and I agree that we don't currently use what is in the CLD to determine what other than concept codes are in the expansion. Is that your point?
that's the primary todo - extend expansion to cover that
Good.
Paul Lynch (Jun 27 2019 at 14:44):
At least for my own purposes, I am using $expand with the filter parameter to determine what comes back in the expansion. I don't see how the CLD has any bearing on what I am doing (though there are likely other use cases for it). With regard to properties, I would like to:
1) Specify in the $expand which properties get returned
2) Specify in the $expand which properties are matched via the filter parameter (in addition to the display values)
Grahame Grieve (Jun 27 2019 at 20:31):
I assume you didn't follow my point. The CLD uses concept identity, properties, relations, etc. to determine expansion concept membership
ah yes. you're right.
Robert McClure (Jun 28 2019 at 16:48):
@Paul Lynch Since you are at the NLM (where?) we should chat directly, offline. PM me. I'm sure I don't understand what you really mean with
I am using $expand with the filter parameter to determine what comes back in the expansion. I don't see how the CLD has any bearing on what I am doing
Because $expand primarily exists to run the CLD for an existing ValueSet resource as an operation. Are you saying you are using $expand without specifying a ValueSet resource you are expanding?
Paul Lynch (Jun 28 2019 at 17:00):
@Robert McClure Ha! I did not realize you were also at NLM! It's a small world (or a large NLM). I did not mean to say the CLD was not necessary. I will follow up with a PM.
Michael Lawley (Jun 28 2019 at 22:55):
@Paul Lynch for your #2, it sounds like you're describing the CLD, or in FHIR terms, the ValueSet.compose
. In this case you would not use the filter parameter, that is explicitly and only for matching designations, but instead POST your own ValueSet definition with whatever property constraints you want directly to the /ValueSet/$expand
operation.
Paul Lynch (Jun 28 2019 at 23:00):
I'm not sure how that would work. In #2, I am trying to fetch expansion results for a ValueSet for which I only have the URI and some property names. I don't see how I could POST a definition for it. My purpose here is to support autocompletion as the user types in a field in a Questionnaire with answerValueSet.
Michael Lawley (Jun 29 2019 at 23:19):
I presume you also have the CodeSystem URI? Let's say it is http://example.com/cs1
, the ValueSet URI is http://example.com/vs1
, the text entered by the user is "foo" and there is one property of interest "myprop", then you would construct ValueSet with a compose like:
"compose": { "include": [ { "system": "http://example.com/cs1", "filter": [ { "property": "myprop", "op": "regex", "value": "foo.*" } ], "valueSet": [ "http://example.com/vs1" ] } ] },
Which is a CLD for the intersection of the codes with a matching property and those in the ValueSet.
If you have multiple properties or you also want to match against the display text, then add extra include clauses.
Robert McClure (Jul 01 2019 at 17:38):
I'll add that in an $expand you could ask for anything that is available from the code system which obviously is likely much more than what was used in the CLD to determine expansion concept membership. One of the interesting thought experiments is if you could even add additional properties to the expand return based on somehow adding in to the $expand, use of a code system supplement.
Paul Lynch (Jul 01 2019 at 20:48):
The context I'm working in is Questionnaire, so I don't have a CodeSystem, but a ValueSet URI from Quesitonnaire.item.answerValueSet, and potentially some property names from the choiceColumn extension. The ValueSet the client is being asked to expand might be an already constrained subset of the codes of the CodeSystem, so in general, even if I had a CodeSystem URI, I could not POST my own ValueSet consisting only of the system and the filters I wanted.
With this scheme, I would first have to request the ValueSet resource (not expanded), edit it to add filters for matching the user's input to whichever properties were requested (by choiceColumn) and the POST the result back to server with an $expand. Does that sound correct? Granted, I would only have to request the ValueSet definition once per ValueSet.
I think it could work, but it does not seem simple or elegant.
Brian Postlethwaite (Jul 01 2019 at 22:31):
A valueset can depend on another valueset rather than a code system, but that still depends on you being able to create a new valueset (and cleanup after) or submit the whole valueset each time you want to expand (which could be a lot during data entry on an auto complete style field.
And my terminology server does pre expansion, so wouldn't work very well like this.
Peter Jordan (Jul 01 2019 at 22:40):
Apologies if I've missed something here - but it might be helpful to have an example of an underlying code system in this use case. If you are attempting to use filters based on properties, these must belong to a Code System (see ValueSet.compose.filter) and that Code System may have a grammar (e.g. ECL in SNOMED CT) that would enable you to make interactive $expansion requests directly to a Terminology Server without the intermediate step of posting ValueSet definitions.
Paul Lynch (Jul 01 2019 at 22:55):
@Brian Postlethwaite Thanks-- I had not noticed that a ValueSet could depend on another ValueSet. That is a much better picture, assuming I can post the new valueset along with the $expand. Creating it ahead of time and then cleaning up afterward would mean three requests, or a batch of three requests. I wonder how many terminology servers will have similar problems.
Brian Postlethwaite (Jul 01 2019 at 22:58):
And posting it each time is going to get pretty heavy.
Brian Postlethwaite (Jul 01 2019 at 23:00):
Would mean that simple terminology servers like mine would be out, and depend on pure terminology servers.
Michael Lawley (Jul 01 2019 at 23:08):
The fragment I posted above re-uses the existing bound valueset (vs1) and adds additional constraints. It depends on the terminology server having access to that valueset, of course.
There are performance considerations; POSTs cannot be cached in the HTTP layer, but they can be cached in the terminology server layer (Ontoserevr will do this, for example).
Michael Lawley (Jul 01 2019 at 23:10):
What concerns me more, however, is the use-case. If the bindings in the Questionnaire are not in your control, then how do you know it is valid to search against additional properties in the Code System(s) of the underlying bound ValueSet?
Michael Lawley (Jul 01 2019 at 23:13):
Picking up on @Peter Jordan s comment, this may be a situation where a general purpose implicit ValueSet syntax akin to SNOMED's ECL may be useful.
On the other hand, if its specific to a particular CodeSystem like LOINC and its answersets, then it may be that teh FHIR Spec should define specific searching behaviour beyond the normal defaults
Michael Lawley (Jul 01 2019 at 23:53):
@Brian Postlethwaite your terminology server could always fall back to an externalised service in such a case.
Paul Lynch (Jul 02 2019 at 14:22):
Whether a grammar would be helpful or not I'm not sure, but the current mechanism for specifying properties to include (for display to the user, and perhaps for the search) is through the choiceColumn extension. The documentation for that extension is not very helpful, but it is better described on the (SDC rendering page](http://build.fhir.org/ig/HL7/sdc/rendering.html#additional-display-content). There does not seem to be any consideration for hierarchical properties, so I think at this point a grammar is not needed (but the problem will eventually arise).
Anyway, to answer @Michael Lawley 's question, the choiceColumn extension is what tells me it is valid (and required) to request those additional properties. The client does not make up additional properties to search; is comes from the Questionnaire definition.
Paul Lynch (Jul 02 2019 at 14:29):
I see @Michael Lawley actually asked about the validity of searching against those properties, not just requesting them. I think it is generally desirable, in an autocompletion setting, to be searching against any properties that are showing up in the list being shown to the user. I suppose the client could check the compatibility statement to see what was allowed? Or maybe it would just try it and fall back to searching in the display value.
Xiaocheng Luan (Jul 05 2019 at 14:44):
Brian Postlethwaite Thanks-- I had not noticed that a ValueSet could depend on another ValueSet. That is a much better picture, assuming I can post the new valueset along with the $expand. Creating it ahead of time and then cleaning up afterward would mean three requests, or a batch of three requests. I wonder how many terminology servers will have similar problems.
It appears that the "filter" is not applicable to valueSet within compose.include?
Lloyd McKenzie (Jul 05 2019 at 15:52):
It should be...
Yunwei Wang (Jul 05 2019 at 15:59):
@Xiaocheng Luan which filter parameter?
Xiaocheng Luan (Jul 05 2019 at 17:31):
Xiaocheng Luan which filter parameter?
Good question - I wasn't clear - I meant the compose.include.filter for the use case/example of creating a ValueSet resource and send to server with the $expand request. But yes, $expand request filter parameter should still work. @Lloyd McKenzie
Michael Lawley (Jul 07 2019 at 22:45):
If your compose.include
has both a filter
and a valueset
, then it is asking for the set of concepts that are in the referenced valueset and match the system
& filter
. That is, the filter
further constrains the valueset.
Brian Postlethwaite (Oct 03 2019 at 03:13):
Outcomes:
- define a way to put properties in expansions in R5 (match the CodeSystem pattern)
- define an extension to put properties in expansions in R4 (matching the CodeSystem pattern)
- define a way for a client to ask for particular properties in expansions : property string 0..* a code or a URI for a property that the client wishes to be returned (or *)
- define a way for a value set to specify the default returned properties
- document the use of :in to search by property value
- define a way for a value set to specify the order if filtered based on properties
Where did we get to with defining this in R5, and was there a format for R4 to expose the properties/extensions in the valueset expansion?
Brian Postlethwaite (Oct 03 2019 at 05:08):
@Michael Lawley , think this is something that could be investigated at your NHS Terminology Connectathon?
Grahame Grieve (Oct 03 2019 at 05:08):
I'll try and work on a draft for this next week.
Grahame Grieve (Oct 03 2019 at 05:09):
might be time to define a ConceptDefinition data type that is used in both CodeSystem (same as what there is now) and also in ValueSet expansion
Brian Postlethwaite (Oct 03 2019 at 06:51):
Thanks, I'll be happy to do some POC code for it in R4 when you have a technique done.
Michael Lawley (Oct 03 2019 at 11:39):
This topic is something that came up during the 1st day of the connectathon.
The main requirement articulated was the desire to be able to ask for "all properties", e.g., with ?property=*
This raises the question of which properties this would automatically include. For example, parent
and child
(in some cases child could be very large).
Rob Hausam (Oct 03 2019 at 11:49):
@Grahame Grieve Can you elaborate a bit more on the ConceptDefinition data type and how you envision it working?
Grahame Grieve (Oct 03 2019 at 19:58):
ConceptDefinition is presently a type defined as part of the CodeSystem resource:
Grahame Grieve (Oct 03 2019 at 19:59):
code | display | definition + designation + property
Grahame Grieve (Oct 03 2019 at 20:00):
.. nah, the two boolean flags means that a trick that won't work. Will have to clone properties onto the Contains type in value set.
Grahame Grieve (Oct 17 2019 at 21:19):
ok I am committing parts 2,4 and 5. part 3 falls out implicitly because of http://build.fhir.org/versions.html#extensions. So that leaves 6 and 7. I don't even remember what either of them are in detail
Michael Lawley (Oct 17 2019 at 21:32):
7 I think, was about getting the expansion contents back ordered based on a property value - @Brian Postlethwaite ?
Grahame Grieve (Oct 17 2019 at 21:35):
well, there could be all sorts of sophistication there... it feels like a whole little language to itself.... But why property based? Wouldn't you want to do it with any intensional value set?
But why would we standardise this? is there a sweet spot?
Michael Lawley (Oct 17 2019 at 21:35):
6 was about something like code:in=valueset.map(c -> c.property)
ie. not matching code against the expansion concepts, but instead against a property of the expansion's concepts
Michael Lawley (Oct 17 2019 at 21:36):
I'm not convinced about 7 -- I suspect most cases could be handled by sorting client-side
Grahame Grieve (Oct 17 2019 at 21:37):
both 6 and 7 sound deliciously complicated
Michael Lawley (Oct 17 2019 at 21:57):
indeed. 6 is somewhat related to the desire to match against code translations.
i.e., say your retrieval valueset vsUri
is defined in terms of ICD10 and your data has a mix of ICD10 and SNOMED and you have an appropriate conceptmap cmUri
from SNOMED to ICD10. You want to be able to say something like ?code:translate(cmUri):in=vsUri
Michael Lawley (Oct 17 2019 at 22:05):
Re 3, this means in R4 we would add (complex) extensions to ValueSet.expansion.contains
with the URI http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property
? What are the URI's of the nested pieces? code
and value
or http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property.code
and http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property.value
?
Grahame Grieve (Oct 17 2019 at 22:14):
first, I think - simple because they are part of how the extension is defined. But I'm not sure we discussed that explicitly
Grahame Grieve (Oct 17 2019 at 22:28):
one thing that comes out of this... we need revisit our definitions of properties. It's all a bit messed up
Michael Lawley (Oct 17 2019 at 22:52):
How do relative URIs in nested extensions get resolved against the absolute parent URI in an extension. It doesn't seem to work using normal URI resolution rules because the resolved URI for the inner extension in :
<extension url="http://hl7.org/fhir/StructureDefinition/patient-citizenship" > <extension url="code" > ...
would be http://hl7.org/fhir/StructureDefinition/code
but I strong suspect the intension is that it's something like http://hl7.org/fhir/StructureDefinition/patient-citizenship/code
Michael Lawley (Oct 17 2019 at 22:55):
The spec (http://build.fhir.org/versions.html#extensions) says this:
Where complex data types have no equivalent in an earlier version, use a complex extension, containing extensions also following this pattern.
Which I can only interpret as requiring use of absolute URIs in the nested extension elements.
Grahame Grieve (Oct 18 2019 at 02:36):
yes I guess it does
Brian Postlethwaite (Oct 18 2019 at 03:27):
6 and 7 weren't in my list of what I was after, just the other ones.
So if there is something to handle that part, i'm good to go and try things out.
Grahame Grieve (Oct 18 2019 at 03:28):
I'm just wrangling with the validator - will be out in the next 24 hours
Brian Postlethwaite (Oct 18 2019 at 03:28):
No stress, thanks.
Michael Lawley (Oct 18 2019 at 05:50):
I'm away that Genomics England have the translate use-case, and it has also come up with UK NHS in the context of maps that deal with code replacement (eg as provided by SNOMED). But then there's the replacedBy property which is another way of tackling this problem.
Grahame Grieve (Oct 18 2019 at 12:08):
so just to be clear about this, some example extensions in R4:
<compose> <include> <system value="http://hl7.org/fhir/CodeSystem/example"/> </include> <extension url="http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.compose.property"> <valueString value="status"/> </extension> </compose>
Grahame Grieve (Oct 18 2019 at 12:09):
that's request for a property in the expansion. And then in expansion (in json):
Grahame Grieve (Oct 18 2019 at 12:15):
"expansion": { "extension": [{ "url": "http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.property", "extension" : [{ "url" : "http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.property.code", "valueCode": "PROPERTY" },{ "url" : "http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.property.uri", "valueUri": "http://loinc.org/property/PROPERTY" }] }], "contains": [{ "system": "http://loinc.org", "version": "2.50", "code": "14647-2", "display": "Cholesterol [Moles/volume] in Serum or Plasma", "extension": [{ "url": "http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property", "extension" : [{ "url" : "http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property.code", "valueCode": "PROPERTY" },{ "url" : "http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property.value[x]", "valueCode": "SCnc" }] }] }, ...
Michael Lawley (Feb 17 2020 at 03:41):
@Grahame Grieve I'd like to start on pre-adoption of R5's properties in expansion results, but I'm concerned that 5.0
is not likely to work and that I may perhaps need to use 4.2
?
Grahame Grieve (Feb 17 2020 at 03:43):
I
Grahame Grieve (Feb 17 2020 at 03:43):
I'm not exactly sure what you you are asking there
Michael Lawley (Feb 17 2020 at 21:53):
Given that the (pre-)R5 version is 4.2.0, should I be using http://hl7.org/fhir/4.2/StructureDefinition/extension-ValueSet.expansion.contains.property.code
? That is, is there anything in the stack (validation?) that interprets these URIs?
Grahame Grieve (Feb 17 2020 at 23:24):
no. R5 extensions are not in the validator framework right now
Grahame Grieve (Feb 17 2020 at 23:25):
by any version
Paul Lynch (Aug 28 2020 at 23:32):
Brian Postlethwaite said:
Outcomes:
- define a way to put properties in expansions in R5 (match the CodeSystem pattern)
- define an extension to put properties in expansions in R4 (matching the CodeSystem pattern)
- define a way for a client to ask for particular properties in expansions : property string 0..* a code or a URI for a property that the client wishes to be returned (or *)
- define a way for a value set to specify the default returned properties
- document the use of :in to search by property value
- define a way for a value set to specify the order if filtered based on properties
Where did we get to with defining this in R5, and was there a format for R4 to expose the properties/extensions in the valueset expansion?
Are there tracker items for these things? I am just wondering whether this exists somewhere outside this thread, so it doesn't get lost.
Brian Postlethwaite (Aug 31 2020 at 21:59):
And can we add it to the connectathon stream for R4?
Brian Postlethwaite (Sep 10 2020 at 18:21):
Hey all, going to do some testing on this, did an implementation of the back-port (expansion results) and wanted to run it past folks.
Grahame Grieve (Sep 10 2020 at 18:31):
ok
Brian Postlethwaite (Sep 10 2020 at 19:50):
How does this look to represent the contains property in the returned results in R4?
Based on the def from http://build.fhir.org/valueset.html
<expansion>
<contains>
<extension url="http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property">
<extension url="code">
<valueCode value="custom-code-prop" />
</extension>
<extension url="value"> <!-- or should this be value[x]-->
<valueString value="custom-code-value" />
</extension>
</extension>
<system value="urn:ietf:bcp:47" />
<code value="de-AT" />
<display value="German (Austria)" />
</contains>
<contains>
<system value="urn:ietf:bcp:47" />
<code value="de-CH" />
<display value="German (Switzerland)" />
</contains>
Brian Postlethwaite (Sep 10 2020 at 19:56):
Sorry, just updated based on notes further up that I'd missed.
any reason why using the full URLs and not just simple values (as in with a complex extension?)
Brian Postlethwaite (Sep 10 2020 at 20:02):
And I don't see any changes to the R4 expand operation to ask for them either?
Do we actually need to compose another valueset that expands the existing valueset and indicate that you want the properties back, and post that?
Grahame Grieve (Sep 10 2020 at 20:03):
no we would just pre-adopt R5 parameters in R4
Brian Postlethwaite (Sep 10 2020 at 20:04):
Sorry, missed the property
parameter. My mistake.
Brian Postlethwaite (Sep 10 2020 at 20:06):
On that backbone element child property extension URLs, any reason for the full name and not just the short one within the context of the fully described parent?
ie. http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property.code
and not just code
Grahame Grieve (Sep 10 2020 at 20:06):
or should this be value[x]
yes
Grahame Grieve (Sep 10 2020 at 20:07):
no. it's worse.
Grahame Grieve (Sep 10 2020 at 20:07):
value_x_
Brian Postlethwaite (Sep 10 2020 at 20:09):
This is where I should be looking right?
http://build.fhir.org/versions.html#extensions
There is nothing in there on backbone elements, nor value[x]
Grahame Grieve (Sep 10 2020 at 20:09):
well, there is by implication on the second:
Grahame Grieve (Sep 10 2020 at 20:10):
The [Path] is actually the ElementDefinition.id from the relevant StructureDefinition for the element
Grahame Grieve (Sep 10 2020 at 20:11):
Agree that there's nothing about backbone elements, to my surprise. Agree that the way you've done it is right.
Grahame Grieve (Sep 10 2020 at 20:12):
would be good to make a task on both these - to point out how value[x[ works, and to agree about backbone elemnets
Brian Postlethwaite (Sep 10 2020 at 20:13):
Will do, I'm looking to try and find where the value_x_ for elementdef.id is documented
Brian Postlethwaite (Sep 10 2020 at 20:20):
@Michael Lawley , did this ever make it into your R4 builds yet?
Grahame Grieve (Sep 10 2020 at 20:33):
you have to look inside the structure definition itself
Brian Postlethwaite (Sep 10 2020 at 20:54):
Michael Lawley (Sep 10 2020 at 22:29):
As I read the spec, the reason for full URIs is that this:
any element defined in any version of FHIR is automatically assigned an extension URL that uniquely identifies the element
So code
and value[x]
have their own URIs:
http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property.code
http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property.value_x_
AFAICT, this is not the same as having a complex extension defined and then being able to use child extension references.
Michael Lawley (Sep 10 2020 at 22:39):
I don't know if there's any infrastructure code that will take, for example, an R5 ValueSet and transform it to the R4 version with extensions?
Michael Lawley (Sep 10 2020 at 22:40):
I'm not sure that we have real clarity here, which is one reason why we haven't merged expansion properties into the Ontoserver dev build yet.
However, if J#28479 is likely to be accepted as proposed, then I'd be comfortable to bring it in, although the window for the next release is rapidly closing.
Brian Postlethwaite (Sep 11 2020 at 00:17):
I'm going to draft this into my server today to try it out with some questionnaire stuff we're doing.
Brian Postlethwaite (Sep 11 2020 at 05:30):
Have implemented and deployed this into my server now too.
Robert McClure (Sep 12 2020 at 19:43):
@Brian Postlethwaite IF this is working on your server, any chance you have rxnorm installed with all it's properties? And I can access it?
Brian Postlethwaite (Sep 12 2020 at 20:14):
My server isn't anywhere near that complex. Just simple stuff manually loaded in via fhir.
Grahame Grieve (Sep 13 2020 at 10:20):
what properties would you care about for RxNorm?
Brian Postlethwaite (Sep 13 2020 at 21:37):
Now that I've done it, this same extension structure could be used on a coding too.
I'm looking for a way to reference the property in a questionnaire without hitting the terminology server again.
Some notes on the connectathon report out. Will follow up again later.
https://confluence.hl7.org/pages/viewpage.action?pageId=86974609#id-202009Questionnaire-Notableachievements:
Grahame Grieve (Sep 13 2020 at 22:17):
well, not so easy, because the code is relative to the definition of it.
Brian Postlethwaite (Sep 14 2020 at 06:36):
Since this is probably what people might find later if searching here for it, you should also include the valueset.expansion.property in the extensions too ensuring that the declaration of what properties were asked for and included in the output explicitly.
Here is an example of it
https://sqlonfhir-r4.azurewebsites.net/fhir/ValueSet/45/$expand?property=s-val
Michael Lawley (Sep 14 2020 at 09:58):
Hmm, I ended up with the following for ValueSet/$expand?url=http://snomed.info/sct?fhir_vs=ecl/>>33015000&property=moduleId&property=effectiveTime&property=parent
(which is different):
<ValueSet xmlns="http://hl7.org/fhir">
<language value="en"/>
<url value="http://snomed.info/sct/32506021000036107/version/20200531?fhir_vs=ecl%2F%3E%3E33015000"/>
<name value="SNOMED CT ECL expression"/>
<status value="active"/>
<experimental value="false"/>
<copyright value="This value set includes content from SNOMED CT, which is copyright © 2002+ International Health Terminology Standards Development Organisation (IHTSDO), and distributed by agreement between IHTSDO and HL7. Implementer use of SNOMED CT is not covered by this agreement"/>
<expansion>
<extension url="http://hl7.org/fhir/StructureDefinition/valueset-unclosed">
<valueBoolean value="true"/>
</extension>
<identifier value="9811e09e-d2f7-4b61-b8d5-51d0343f3750"/>
<timestamp value="2020-09-14T19:54:29+10:00"/>
<total value="54"/>
<offset value="0"/>
<parameter>
<name value="version"/>
<valueUri value="http://snomed.info/sct|http://snomed.info/sct/32506021000036107/version/20200531"/>
</parameter>
<parameter>
<name value="count"/>
<valueInteger value="2147483647"/>
</parameter>
<parameter>
<name value="offset"/>
<valueInteger value="0"/>
</parameter>
<contains>
<extension url="http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property">
<extension url="parent">
<valueCode value="108191006"/>
</extension>
<extension url="parent">
<valueCode value="118869008"/>
</extension>
<extension url="parent">
<valueCode value="83607001"/>
</extension>
<extension url="parent">
<valueCode value="120200004"/>
</extension>
<extension url="effectiveTime">
<valueString value="20020131"/>
</extension>
<extension url="moduleId">
<valueString value="900000000000207008"/>
</extension>
</extension>
<system value="http://snomed.info/sct"/>
<code value="120058006"/>
<display value="Fallopian tube endoscopy"/>
</contains>
<contains>
<extension url="http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property">
<extension url="parent">
<valueCode value="108193009"/>
</extension>
<extension url="parent">
<valueCode value="392250009"/>
</extension>
<extension url="parent">
<valueCode value="45835000"/>
</extension>
<extension url="parent">
<valueCode value="363068004"/>
</extension>
<extension url="parent">
<valueCode value="128422009"/>
</extension>
<extension url="effectiveTime">
<valueString value="20110131"/>
</extension>
<extension url="moduleId">
<valueString value="900000000000207008"/>
</extension>
</extension>
<system value="http://snomed.info/sct"/>
<code value="447192001"/>
<display value="Electrodestruction of fallopian tube"/>
</contains>
Brian Postlethwaite (Sep 14 2020 at 10:36):
There is no property parent on that backbone element.
Brian Postlethwaite (Sep 14 2020 at 10:38):
parent
in your example here is a code value in the code
child complex extension, the value Code value is to the value_x_
extension
Brian Postlethwaite (Sep 14 2020 at 10:40):
And it's missing the property child directly under expansion which lists the code to Uri for the properties included.
Michael Lawley (Sep 14 2020 at 10:44):
ah, of course, now I get the model - thanks!
Brian Postlethwaite (Sep 14 2020 at 10:45):
Can you see the example from my server for comparison?
Michael Lawley (Sep 14 2020 at 11:01):
So this is what I have now:
<ValueSet xmlns="http://hl7.org/fhir">
<language value="en"/>
<url value="http://snomed.info/sct/32506021000036107/version/20200531?fhir_vs=ecl%2F%3E%3E33015000"/>
<name value="SNOMED CT ECL expression"/>
<status value="active"/>
<experimental value="false"/>
<copyright value="This value set includes content from SNOMED CT, which is copyright © 2002+ International Health Terminology Standards Development Organisation (IHTSDO), and distributed by agreement between IHTSDO and HL7. Implementer use of SNOMED CT is not covered by this agreement"/>
<expansion>
<extension url="http://hl7.org/fhir/StructureDefinition/valueset-unclosed">
<valueBoolean value="true"/>
</extension>
<identifier value="b41ab029-ac70-41f2-919a-35993e46b1af"/>
<timestamp value="2020-09-14T21:19:09+10:00"/>
<total value="54"/>
<offset value="0"/>
<parameter>
<name value="version"/>
<valueUri value="http://snomed.info/sct|http://snomed.info/sct/32506021000036107/version/20200531"/>
</parameter>
<parameter>
<name value="count"/>
<valueInteger value="2"/>
</parameter>
<parameter>
<name value="offset"/>
<valueInteger value="0"/>
</parameter>
<contains>
<extension url="http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property">
<extension url="code">
<valueCode value="parent"/>
</extension>
<extension url="value_x_">
<valueCode value="108191006"/>
</extension>
</extension>
<extension url="http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property">
<extension url="code">
<valueCode value="parent"/>
</extension>
<extension url="value_x_">
<valueCode value="118869008"/>
</extension>
</extension>
<extension url="http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property">
<extension url="code">
<valueCode value="parent"/>
</extension>
<extension url="value_x_">
<valueCode value="83607001"/>
</extension>
</extension>
<extension url="http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property">
<extension url="code">
<valueCode value="parent"/>
</extension>
<extension url="value_x_">
<valueCode value="120200004"/>
</extension>
</extension>
<extension url="http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property">
<extension url="code">
<valueCode value="effectiveTime"/>
</extension>
<extension url="value_x_">
<valueString value="20020131"/>
</extension>
</extension>
<extension url="http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property">
<extension url="code">
<valueCode value="moduleId"/>
</extension>
<extension url="value_x_">
<valueString value="900000000000207008"/>
</extension>
</extension>
<system value="http://snomed.info/sct"/>
<code value="120058006"/>
<display value="Fallopian tube endoscopy"/>
</contains>
<contains>
<extension url="http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property">
<extension url="code">
<valueCode value="parent"/>
</extension>
<extension url="value_x_">
<valueCode value="108193009"/>
</extension>
</extension>
<extension url="http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property">
<extension url="code">
<valueCode value="parent"/>
</extension>
<extension url="value_x_">
<valueCode value="392250009"/>
</extension>
</extension>
<extension url="http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property">
<extension url="code">
<valueCode value="parent"/>
</extension>
<extension url="value_x_">
<valueCode value="45835000"/>
</extension>
</extension>
<extension url="http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property">
<extension url="code">
<valueCode value="parent"/>
</extension>
<extension url="value_x_">
<valueCode value="363068004"/>
</extension>
</extension>
<extension url="http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property">
<extension url="code">
<valueCode value="parent"/>
</extension>
<extension url="value_x_">
<valueCode value="128422009"/>
</extension>
</extension>
<extension url="http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property">
<extension url="code">
<valueCode value="effectiveTime"/>
</extension>
<extension url="value_x_">
<valueString value="20110131"/>
</extension>
</extension>
<extension url="http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property">
<extension url="code">
<valueCode value="moduleId"/>
</extension>
<extension url="value_x_">
<valueString value="900000000000207008"/>
</extension>
</extension>
<system value="http://snomed.info/sct"/>
<code value="447192001"/>
<display value="Electrodestruction of fallopian tube"/>
</contains>
</expansion>
</ValueSet>
Brian Postlethwaite (Sep 14 2020 at 11:05):
That's extensive :laughing:
Michael Lawley (Sep 14 2020 at 11:06):
WIP -- I posted then noticed a bug! - no way to delete the message AFAICT
Michael Lawley (Sep 14 2020 at 11:20):
how's that?
Brian Postlethwaite (Sep 14 2020 at 21:41):
That's good, and to complete just needs the extension for the valueset.expansion.property
to declare the full Uri for the property codes from the CodeSystem and its the same as what I've done.
Michael Lawley (Sep 14 2020 at 22:51):
Hmm, interesting. Why do properties get re-declared in the expansion?
Brian Postlethwaite (Sep 15 2020 at 00:05):
Isn't that to provide what the canonical URI is for the code declaration is that is in the concepts in the expansion?
Brian Postlethwaite (Sep 15 2020 at 00:05):
(It's in the R5 valueset definition)
Michael Lawley (Sep 15 2020 at 00:08):
I see it in the R5 definition, but doesn't this duplicate the declaration from the CodeSystem?
Grahame Grieve (Sep 15 2020 at 00:09):
it's not the code system
Michael Lawley (Sep 15 2020 at 00:10):
Sure, but the CodeSystem already includes this information (and presumably it is the actual source of it). I'm wondering what the need is to replicate it?
Grahame Grieve (Sep 15 2020 at 00:11):
we didn't - and couldn't - make a rule that the code must match
Michael Lawley (Sep 15 2020 at 00:12):
meaning that the CS make declare http://example.com/prop/foo
and foo
but the VS expansion may have http://example.com/prop/foo
and bar
?
Grahame Grieve (Sep 15 2020 at 00:12):
it could. yes.
Michael Lawley (Sep 15 2020 at 00:14):
So all clients need to reconcile the actual property code back to the property URI?
When is this needed? (for the VS to use different property codes to the CS?)
Grahame Grieve (Sep 15 2020 at 00:20):
because an expansion can cover multiple code systems, and the code systems could define clashing property codes (which is why they also define URIs)
Michael Lawley (Sep 15 2020 at 02:14):
But...you know which system any given concept is from, so the property code is always relative to that system
Grahame Grieve (Sep 15 2020 at 02:14):
that's true
Grahame Grieve (Sep 15 2020 at 02:17):
so you're effectively proposing that we should say that properties in expansions always SHALL use the code defined for the property in the code system, and the property code in the expansion is scoped by the system
Michael Lawley (Sep 15 2020 at 02:25):
yes, very much so. otherwise you're pushing significant additional complexity onto clients
Grahame Grieve (Sep 15 2020 at 02:29):
I don't know that we are. We're just moving the resolution to URI from the expansion to the code system.
Brian Postlethwaite (Sep 15 2020 at 02:36):
and forcing the lookup back to the codesystem too by the client as a seperate action.
Michael Lawley (Sep 15 2020 at 02:38):
If it's fixed in the CodeSystem, then clients can make assumptions. If it can be varied in the ValueSet, then clients cannot make assumptions.
Grahame Grieve (Sep 15 2020 at 02:46):
I think that's over stating it. Under the current system, it's tied to the uri defined in the code system. Michael proposes to change that being tied to the code in the code system. I'm not seeing a very significant change here
Brian Postlethwaite (Sep 15 2020 at 03:47):
It's stating that the property URI is meaningless then?
Grahame Grieve (Sep 15 2020 at 03:50):
I don't think that's the case; It's still meaningful in other ways even if it's not directly implicated here
Michael Lawley (Sep 15 2020 at 06:26):
My concern is whether a client can assume that the property code moduleId
in a VS expansion on a SNOMED concept corresponds to the moduleId
code as defined for SNOMED. Instead, it needs to check that the associated URI listed in the VS expansion corresponds to that listed in the CS.
Michael Lawley (Sep 15 2020 at 06:28):
I note that a $lookup
doesn't give you back the property-code -> URI mapping
Last updated: Apr 12 2022 at 19:14 UTC