diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_3_0/2309-name-text-search.yaml b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_3_0/2309-name-text-search.yaml new file mode 100644 index 00000000000..30bf181cd56 --- /dev/null +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_3_0/2309-name-text-search.yaml @@ -0,0 +1,4 @@ +--- +type: fix +issue: 2309 +title: "In the JPA server, HumanName.name.text was not being indexed and therefore was not searchable. This has been corrected." diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/SearchParamExtractorR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/SearchParamExtractorR4Test.java index a680c5a27db..d29371959ad 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/SearchParamExtractorR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/SearchParamExtractorR4Test.java @@ -30,6 +30,7 @@ import org.hl7.fhir.r4.model.Coding; import org.hl7.fhir.r4.model.Consent; import org.hl7.fhir.r4.model.Encounter; import org.hl7.fhir.r4.model.Extension; +import org.hl7.fhir.r4.model.HumanName; import org.hl7.fhir.r4.model.Observation; import org.hl7.fhir.r4.model.Patient; import org.hl7.fhir.r4.model.Quantity; @@ -50,6 +51,8 @@ import java.util.Set; import java.util.stream.Collectors; import static java.util.Comparator.comparing; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsInAnyOrder; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -82,6 +85,19 @@ public class SearchParamExtractorR4Test { assertEquals("CODE", token.getValue()); } + @Test + public void testName() { + Patient patient = new Patient(); + HumanName humanName = patient.addName(); + humanName.addGiven("Jimmy"); + humanName.setFamily("Jones"); + humanName.setText("Jimmy Jones"); + SearchParamExtractorR4 extractor = new SearchParamExtractorR4(new ModelConfig(), new PartitionSettings(), ourCtx, mySearchParamRegistry); + ISearchParamExtractor.SearchParamSet stringSearchParams = extractor.extractSearchParamStrings(patient); + List nameValues = stringSearchParams.stream().filter(param -> "name".equals(param.getParamName())).map(ResourceIndexedSearchParamString::getValueExact).collect(Collectors.toList()); + assertThat(nameValues, containsInAnyOrder("Jimmy", "Jones", "Jimmy Jones")); + } + @Test public void testTokenOnSearchParamContext() { SearchParameter sp = new SearchParameter(); diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/BaseSearchParamExtractor.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/BaseSearchParamExtractor.java index d2324ef102f..10c8bd2ce2d 100644 --- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/BaseSearchParamExtractor.java +++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/BaseSearchParamExtractor.java @@ -132,6 +132,7 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor private BaseRuntimeChildDefinition myDurationValueValueChild; private BaseRuntimeChildDefinition myHumanNameFamilyValueChild; private BaseRuntimeChildDefinition myHumanNameGivenValueChild; + private BaseRuntimeChildDefinition myHumanNameTextValueChild; private BaseRuntimeChildDefinition myContactPointValueValueChild; private BaseRuntimeChildDefinition myIdentifierSystemValueChild; private BaseRuntimeChildDefinition myIdentifierValueValueChild; @@ -877,6 +878,10 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor for (String next : givens) { createStringIndexIfNotBlank(theResourceType, theParams, theSearchParam, next); } + List texts = extractValuesAsStrings(myHumanNameTextValueChild, theValue); + for (String next : texts) { + createStringIndexIfNotBlank(theResourceType, theParams, theSearchParam, next); + } } private void addString_Quantity(String theResourceType, Set theParams, RuntimeSearchParam theSearchParam, IBase theValue) { @@ -1138,6 +1143,7 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor BaseRuntimeElementCompositeDefinition humanNameDefinition = (BaseRuntimeElementCompositeDefinition) getContext().getElementDefinition("HumanName"); myHumanNameFamilyValueChild = humanNameDefinition.getChildByName("family"); myHumanNameGivenValueChild = humanNameDefinition.getChildByName("given"); + myHumanNameTextValueChild = humanNameDefinition.getChildByName("text"); BaseRuntimeElementCompositeDefinition contactPointDefinition = (BaseRuntimeElementCompositeDefinition) getContext().getElementDefinition("ContactPoint"); myContactPointValueValueChild = contactPointDefinition.getChildByName("value");