How should Observation combo-code-value-quantity search should work

Hi there,

I am trying to figure out how combo-code-value-quantity for Observation should work.

Assume we have a Observation document with the following snippets:

  "code": {
    "coding": [
      {
        "system": "http://loinc.org",
        "code": "85354-9",
        "display": "Bood pressure panel with all children optional"
      }
    ],
    "text": "Blood pressure systolic & diastolic"
  },
  "component": [
    {
      "code": {
        "coding": [
          {
            "system": "http://loinc.org",
            "code": "8480-6",
            "display": "Systolic blood pressure"
          },
          {
            "system": "http://snomed.info/sct",
            "code": "271649006",
            "display": "Systolic blood pressure"
          },
          {
            "system": "http://acme.org/devices/clinical-codes",
            "code": "bp-s",
            "display": "Systolic Blood pressure"
          }
        ]
      },
      "valueQuantity": {
        "value": 107,
        "unit": "mmHg",
        "system": "http://unitsofmeasure.org",
        "code": "mm[Hg]"
      },
      "interpretation": {
        "coding": [
          {
            "system": "http://hl7.org/fhir/v2/0078",
            "code": "N",
            "display": "normal"
          }
        ],
        "text": "Normal"
      }
    },
    {
      "code": {
        "coding": [
          {
            "system": "http://loinc.org",
            "code": "8462-4",
            "display": "Diastolic blood pressure"
          }
        ]
      },
      "valueQuantity": {
        "value": 60,
        "unit": "mmHg",
        "system": "http://unitsofmeasure.org",
        "code": "mm[Hg]"
      },
      "interpretation": {
        "coding": [
          {
            "system": "http://hl7.org/fhir/v2/0078",
            "code": "L",
            "display": "low"
          }
        ],
        "text": "Below low normal"
      }
    }
  ]

Here are some search query and expected behaviors:

combo-code-value-quantity=http://loinc.org|85354-9$107|http://unitsofmeasure.org|mm[Hg]

This should match since it’s searching by using code “blood pressure” with value 107.

combo-code-value-quantity=http://loinc.org|8480-6$107|http://unitsofmeasure.org|mm[Hg]
combo-code-value-quantity=http://snomed.info/sct|271649006$107|http://unitsofmeasure.org|mm[Hg]

These should match since it’s searching by using code “Systolic blood pressure” with value 107.

combo-code-value-quantity=http://loinc.org|8462-4$60|http://unitsofmeasure.org|mm[Hg]

This should match since it’s searching by using code “Diastolic blood pressure” with value 60.

combo-code-value-quantity=http://loinc.org|8480-6$60|http://unitsofmeasure.org|mm[Hg]

This should not match since it’s searching by using code “Systolic blood pressure” with value 60, which is not true.

Is my understanding above correct? Logically speaking, the last one should not match since Systolic value is not 60. Running the search through HAPI, it would actually match. So I am trying to figure out if my understanding is incorrect or if this is a bug in HAPI.

If the last query should not match, then I am wondering how we can programmatically do that using the search parameter definition without semantically parsing the expression itself.

The search parameter is defined as the following:

    {
      "fullUrl": "http://hl7.org/fhir/SearchParameter/Observation-combo-code-value-quantity",
      "resource": {
        "resourceType": "SearchParameter",
        "id": "Observation-combo-code-value-quantity",
        "url": "http://hl7.org/fhir/SearchParameter/Observation-combo-code-value-quantity",
        "name": "combo-code-value-quantity",
        "status": "draft",
        "experimental": false,
        "date": "2017-04-19T07:44:43+10:00",
        "publisher": "Health Level Seven International (Orders and Observations)",
        "contact": [
          {
            "telecom": [
              {
                "system": "url",
                "value": "http://hl7.org/fhir"
              }
            ]
          },
          {
            "telecom": [
              {
                "system": "url",
                "value": "http://www.hl7.org/Special/committees/orders/index.cfm"
              }
            ]
          }
        ],
        "code": "combo-code-value-quantity",
        "base": [
          "Observation"
        ],
        "type": "composite",
        "description": "Code and quantity value parameter pair, including in components",
        "expression": "Observation | Observation.component",
        "xpathUsage": "normal",
        "component": [
          {
            "definition": {
              "reference": "http://hl7.org/fhir/SearchParameter/Observation-combo-code"
            },
            "expression": "code"
          },
          {
            "definition": {
              "reference": "http://hl7.org/fhir/SearchParameter/Observation-combo-value-quantity"
            },
            "expression": "value.as(Quantity)"
          }
        ]
      }
    },

The current logic is to evaluate expression Observation | Observation.component, which will produce a list of elements (the parent Observation and all of the components of the Observation), then enumerate each search parameter component (in this case, the code and value.as(Quantity)) on each of those element. Finally, produce a cartesian product of all of the elements found.

This produces:

code:

value:

  • 107|http://unitsofmeasure.org|mm[Hg]
  • 60|http://unitsofmeasure.org|mm[Hg]

Producing a cartesian product will create the invalid entry, but I also don’t see how we can say something like code and value can mix between Observation and its components but not between components from the definition itself.

If we don’t have to support the first scenario (e.g., http://loinc.org|85354-9$107|http://unitsofmeasure.org|mm[Hg] aka searching by using code “blood pressure” with value from component), then perhaps what we can do is only evaluate the search parameter component on individual element extracted from the expression. E.g., it will only support Observation.code + Observation.value.as(Quantity), Observation.component[0].code + Observation.component[0].value.as(Quantity), Observation.component[1].code + Observation.component[1].value.as(Quantity).

The caller can always put 85354-9 in each individual component anyways to enable searching using code “blood pressure” + individual value.

My expectation is that the code-value combo must appear at the same level. So 85354-9 with a value of 107 would not match because there is no Observation.value of 107. (The Observation.component.value of 107 would not count.) However, this would be a good thing to clarify in the specification. Please submit a change request.

The other statements are all correct. The code + values are matched within each component repetition and do not span components.

The way the process works is that the expression identifies all of the elements for which the search components get evaluated. But the evaluations are separate. So it’s code & value.as(Quantity) of the Observation, then code & value of the first component, then second component, etc. If you don’t think that’s sufficient clear in the specification, you can submit a change request on that too.

Thanks Lloyd.

What you described makes total sense. I will file the change request to clarify that on the spec.