.Net Fhir Bundle Search

295 views
Skip to first unread message

Dimitrios Soulakas

unread,
Aug 4, 2017, 9:02:34 AM8/4/17
to FHIR DOTNET
var endpoint = new Uri(FHIRserver_comboBox.Text);
            var client = new FhirClient(endpoint);
            patientName = patientName_txtBox.Text;

var query = new string[] { "name=" + patientName + "" };

var bundle = client.Search("Patient", query);


foreach (var entry in bundle.Entry)
            {
label1.Text = label1.Text + "id: " + p.Id + " | " + "surname: " + p.Name.First().Family.FirstOrDefault() + " | " + "name: " + p.Name.First().Given.FirstOrDefault() + " | " + "birthdate: " + p.BirthDate + " | " + "gender: " + p.Gender + " | " + "careprovider: " + org.Name + pract.Name + "" + "\r\n";

            }

I want to ask if there is a way to show in my label the practitioner of the patient (i want the result of that to be based of the patient name) !

Mirjam Baltus

unread,
Aug 14, 2017, 8:51:18 AM8/14/17
to FHIR DOTNET
The reference to the practitioner would be in p.GeneralPractitioner, but unless the display value has been set, this is just a pointer to the information. If the display is not set, you will need to perform the query with an _include of the Practitioner information, then search in the Bundle for that Practitioner resource and take the name from it to put in your label.

The _include in your search:

var query = new SearchParams()
                     
.Where("name=" + patientName)
                     
.Include("Patient:general-practitioner");

Note that your result Bundle could include several types of resources now (Patient, Practitioner, Organization and perhaps OperationOutcome), so you will need to check the type of the bundle.Entry in your loop.
For example:

if (entry.Resource.ResourceType == ResourceType.Patient)
{
   
// build the string with patient information
}



Dimitrios Soulakas

unread,
Aug 14, 2017, 1:45:23 PM8/14/17
to FHIR DOTNET
Exception thrown: 'Hl7.Fhir.Rest.FhirOperationException' in Hl7.Fhir.DSTU2.Core.dll
Exception thrown: '<unknown>' in Unknown Module.
The program '[11836] FHIR Windows Form Application Test.vshost.exe: Program Trace' has exited with code 0 (0x0).
The program '[11836] FHIR Windows Form Application Test.vshost.exe' has exited with code 0 (0x0).

Mirjam Baltus

unread,
Aug 14, 2017, 3:01:31 PM8/14/17
to FHIR DOTNET
Ah, okay, I didn't know you were still working with the DSTU2 version of FHIR. There were some changes from DSTU2 to STU3, both in the specification and in the API. One is the GeneralPractitioner field, which was still called CareProvider in DSTU2. And perhaps the DSTU2 API doesn't have the SearchParams construction I used.
But without your code, and without knowing the version of the server you connected to, I can't tell for sure what caused this exception.

Mirjam Baltus

unread,
Aug 17, 2017, 7:24:13 AM8/17/17
to FHIR DOTNET
I was notified through email that you had posted a reaction to this thread, but don't see it here anymore.
The problem you had when you removed DSTU2 and installed STU3 was probably a Visual Studio error. Restarting the app could help, or in some cases removing the API, then restarting and re-adding the API.

The search in my example used the SearchParams construction to create a query. In that case, you will need to supply the type to the Search, like this:

var bundle = client.Search<Patient>(query);

If you do not like that, you can still use the construction you had previously, with query being a string array, and the type supplied as extra string parameter.

Mirjam Baltus

unread,
Aug 17, 2017, 10:53:13 AM8/17/17
to FHIR DOTNET
Again, your reaction is invisible to me on the forum, but I did get an email. Not sure why that is... computers... :D

"For now i want to ask about p.GeneralPractitioner. When i use it says System.Collections.Generic.List'1[Hl7.Fhir.Model.ResourceReference] , what i want to ask is how to use this reference to display the name of the practitioner. 
Thanks in advance and sorry for the annoyance,

Soulakas DImitris"


No problem, I hope I can make things clearer for you.

In FHIR, resources link together through references. These references are basically pointers to the location where more information can be found.

So in Patient, if you look at the definition in the specs, there is the field 'generalPractitioner', which is of type Reference and is 0..*.

This means that in the API the Patient.GeneralPractitioner is a List of references.

If you lookup the Reference type in the specs, you see that the structure offers a field for the 'reference' string itself, but also a 'display' value.

Now you're in luck if your server has stored that display value, because that would mean you can use that value to show the display name, without the need to include the complete Practitioner or Organization resource in your search. You could just use:


var first_care_provider = p.GeneralPractitioner.First().Display;

But more often the reference will just have the reference string, and you will need to get the extra data from the server.


This can be done in two ways. The first is to include the general-practitioner in your search, as already described above.

In your loop through the entries, you will need to take a look at p.GeneralPractitioner.First().Reference. Then you will need to look in the Bundle to find this reference inside one of the fullUrls of the entries. If you find it, then you can look at that resource information and get the name of the Organization or Practitioner from it.


Here's a code example for that, but note that I only look at the first care provider that might be in the list and put in only a couple of safeguards against empty data:


foreach (var entry in bundle.Entry)
{

   
var my_text = "";

   
if (entry.Resource.ResourceType == ResourceType.Patient)
   
{
       
var p = (Patient)entry.Resource;

       
var GP_name = "";
       
if (p.GeneralPractitioner.Count > 0)
       
{
           
// this gets the reference and converts it to an absolute one if necessary
           
var GP_id = p.GeneralPractitioner.First().GetAbsoluteUriForReference(entry.GetResourceLocation().AbsoluteUri);

           
// find the referenced resource in the bundle
           
var first_GP_resource = bundle.FindEntry(GP_id).First().Resource;

           
if (first_GP_resource.ResourceType == ResourceType.Practitioner)
           
{
               
var prac = (Practitioner)first_GP_resource;
                GP_name
= "Dr. " + prac.Name.First().Family;
           
}
           
else if (first_GP_resource.ResourceType == ResourceType.Organization)
           
{
               
var org = (Organization)first_GP_resource;
                GP_name
= "organization " + org.Name;
           
}
       
}

        my_text
= "id: " + p.Id + " | " + "surname: " + p.Name.First().Family + " | " + "name: " + p.Name.First().Given.FirstOrDefault() + " | " +
                 
"birthdate: " + p.BirthDate + " | " + "gender: " + p.Gender + " | " + "careprovider: " + GP_name + "\r\n";
   
}
}


The second way is to keep the original search and in your loop retrieve the care provider information with an additional call to the server. Note that for brevity I assume p.GeneralPractitioner is of type Practitioner.

foreach (var entry in bundle.Entry)
{

   
var my_text = "";
   
var p = (Patient)entry.Resource;

   
var GP_name = "";
   
if (p.GeneralPractitioner.Count > 0)
   
{
       
var first_GP_resource = client.Read<Practitioner>(p.GeneralPractitioner.First().Reference);
        GP_name
= "Dr. " + first_GP_resource.Name.First().Family;
   
}

    my_text
= "id: " + p.Id + " | " + "surname: " + p.Name.First().Family + " | " + "name: " + p.Name.First().Given.FirstOrDefault() + " | " +
             
"birthdate: " + p.BirthDate + " | " + "gender: " + p.Gender + " | " + "careprovider: " + GP_name + "\r\n";
}

Hope this helps!








Mirjam Baltus

unread,
Aug 18, 2017, 8:44:48 AM8/18/17
to FHIR DOTNET
Of course you are free to change the code to better suit your needs, and perhaps also put in some error handling etc.

Bundles can contain all types of resources at once. A search result for a simple search will usually be a Bundle with just one type of resource inside. But as soon as you include or reverse include extra data, the Bundle will have multiple types. You can construct your own Bundle as well, with several types of resources inside. Please be sure to read the page about Bundles in the specification, so you know which fields are mandatory, which Bundle type would be your best choice and which extra constraints there are on Bundles.

By the way, FHIR is an international standard, so you will see that even though the US has had an influence on the available fields and resource types, so have European coutries, Australia, Canada and others around the world. For instance for Patient it is customary to have race and mothers maiden name filled in for the US, but not for Europe, so these fields are not in the standard Patient definition. Of course the definition might also lack some fields you are used to, but that's why FHIR provides you with an extension mechanism.

Kind regards!

Mirjam
Reply all
Reply to author
Forward
0 new messages