Searching/Querying by resource `extension`
# support
n
How might I search a resource (or set filter criteria for a Subscription) based on an extensions existence (or non existence) by url or by value? I tried using the
_filter
option as:
Resource?_filter=extension ni {url}
But I get an error
Unknown search parameter: extension
Wasn't have much success searching existing support items or docs for searching/querying by extension I wonder if this is a use case for a custom
SearchParameter
? I tried setting one up but am getting an unknown search parameter
{search-param-name}
error.
r
HI @node , medplum's current implementation doesn't allow searching on extensions. For performance reasons, we index the known search parameters.
But we have some options for you re: subscriptions!
We provide an extension on subscriptions called "Expression-based criteria": https://www.medplum.com/docs/subscriptions/subscription-extensions#expression-based-criteria
This allows you to use a FHIR path expression to refine the criteria of your subscription. Using this, you can define an expression to look for the value of this extension
n
Ah that is a great extension for subscriptions! In that case, does this look correct?
Copy code
ts
import { BotEvent, MedplumClient } from '@medplum/core';
import { Communication, Subscription } from '@medplum/fhirtypes';
import Sentiment from 'sentiment';

const sentiment = new Sentiment();

const SENTIMENT_EXTENSION_URL = 'http://example.com/extensions/sentiment';

export const subscription: Subscription = {
  resourceType: 'Subscription',
  reason: 'Communication sentiment analysis',
  status: 'active',
  criteria: `Communication`,
  extension: [
    {
      // https://www.medplum.com/docs/subscriptions/subscription-extensions#expression-based-criteria
      url: 'https://medplum.com/fhir/StructureDefinition/fhir-path-criteria-expression',
      valueString: `not %previous.extension.exists(url = "${SENTIMENT_EXTENSION_URL}")`,
    },
  ],
};

export async function handler(medplum: MedplumClient, event: BotEvent<Communication>): Promise<any> {
  const communication = event.input;

  const content = communication.payload?.at(0)?.contentString;
  if (!content) {
    return;
  }

  const extension = communication.extension ?? [];

  const sentimentExt = extension.some((ext) => ext.url === SENTIMENT_EXTENSION_URL);
  if (sentimentExt) {
    return;
  }

  // possibly find & filter by patient language depending on your sentiment analysis implementations language support

  const sentiment = await getSentiment(content);

  await medplum.updateResource({
    ...communication,
    extension: extension.concat({
      url: SENTIMENT_EXTENSION_URL,
      valueString: JSON.stringify(sentiment),
    }),
  });
}

const getSentiment = async (message: string): Promise<{ score: number; comparative: number }> => {
  return sentiment.analyze(message);
};
Although, I suppose a more appropriate check would be if the previous payload content string is different than the current so sentiment can be reanalyzed on content change (assuming the client allowed it)
r
I think this looks right as far as I can tell. As I understand it, you're subscribing to
Communications
that don't a sentiment extension present ?
n
yup - okay cool appreciate your support here!
k
You mentioned "medplum's current implementation doesn't allow searching on extensions" on 12/2023. I assume this is still the case today?
r
yes, this is still the case!
150 Views