Supported composite sort

This commit is contained in:
Frank Tao 2020-12-11 21:50:32 -05:00
parent a63565bd15
commit dcbdc83d8e
7 changed files with 597 additions and 86 deletions

View File

@ -444,7 +444,7 @@ public class SearchBuilder implements ISearchBuilder {
if (generatedSql.isMatchNothing()) {
return Optional.empty();
}
SearchQueryExecutor executor = mySqlBuilderFactory.newSearchQueryExecutor(generatedSql, myMaxResultsToFetch);
return Optional.of(executor);
}
@ -528,9 +528,25 @@ public class SearchBuilder implements ISearchBuilder {
break;
case QUANTITY:
theQueryStack.addSortOnQuantity(myResourceName, theSort.getParamName(), ascending);
break;
case COMPOSITE:
List<RuntimeSearchParam> theCompositList = param.getCompositeOf();
if (theCompositList == null) {
throw new InvalidRequestException("The composite _sort parameter " + theSort.getParamName() + " is not defined by the resource " + myResourceName);
}
if (theCompositList.size() != 2) {
throw new InvalidRequestException("The composite _sort parameter " + theSort.getParamName()
+ " must have 2 composite types declared in parameter annotation, found "
+ theCompositList.size());
}
RuntimeSearchParam left = theCompositList.get(0);
RuntimeSearchParam right = theCompositList.get(1);
createCompositeSort(theQueryStack, myResourceName, left.getParamType(), left.getName(), ascending);
createCompositeSort(theQueryStack, myResourceName, right.getParamType(), right.getName(), ascending);
break;
case SPECIAL:
case COMPOSITE:
case HAS:
default:
throw new InvalidRequestException("This server does not support _sort specifications of type " + param.getParamType() + " - Can't serve _sort=" + theSort.getParamName());
@ -542,6 +558,37 @@ public class SearchBuilder implements ISearchBuilder {
createSort(theQueryStack, theSort.getChain());
}
private void createCompositeSort(QueryStack theQueryStack, String theResourceName, RestSearchParameterTypeEnum theParamType, String theParamName, boolean theAscending) {
switch (theParamType) {
case STRING:
theQueryStack.addSortOnString(myResourceName, theParamName, theAscending);
break;
case DATE:
theQueryStack.addSortOnDate(myResourceName, theParamName, theAscending);
break;
case REFERENCE:
theQueryStack.addSortOnResourceLink(myResourceName, theParamName, theAscending);
break;
case TOKEN:
theQueryStack.addSortOnToken(myResourceName, theParamName, theAscending);
break;
case NUMBER:
theQueryStack.addSortOnNumber(myResourceName, theParamName, theAscending);
break;
case URI:
theQueryStack.addSortOnUri(myResourceName, theParamName, theAscending);
break;
case QUANTITY:
theQueryStack.addSortOnQuantity(myResourceName, theParamName, theAscending);
break;
default:
throw new InvalidRequestException("This server does not support _sort specifications of type "
+ theParamType + " - Can't serve _sort=" + theParamName);
}
}
private void doLoadPids(Collection<ResourcePersistentId> thePids, Collection<ResourcePersistentId> theIncludedPids, List<IBaseResource> theResourceListToPopulate, boolean theForHistoryOperation,
Map<ResourcePersistentId, Integer> thePosition) {

View File

@ -2063,20 +2063,80 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
@Test()
public void testSortByComposite() {
Observation o = new Observation();
o.getCode().setText("testSortByComposite");
myObservationDao.create(o, mySrd);
IIdType pid0;
IIdType oid1;
IIdType oid2;
IIdType oid3;
IIdType oid4;
{
Patient patient = new Patient();
patient.addIdentifier().setSystem("urn:system").setValue("001");
patient.addName().addFamily("Tester").addGiven("Joe");
pid0 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless();
}
{
Observation obs = new Observation();
obs.addIdentifier().setSystem("urn:system").setValue("FOO");
obs.getSubject().setReference(pid0);
obs.getCode().addCoding().setCode("2345-7").setSystem("http://loinc.org");
obs.setValue(new StringDt("200"));
oid1 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
ourLog.info("Observation: \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
{
Observation obs = new Observation();
obs.addIdentifier().setSystem("urn:system").setValue("FOO");
obs.getSubject().setReference(pid0);
obs.getCode().addCoding().setCode("2345-7").setSystem("http://loinc.org");
obs.setValue(new StringDt("300"));
oid2 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
ourLog.info("Observation: \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
{
Observation obs = new Observation();
obs.addIdentifier().setSystem("urn:system").setValue("FOO");
obs.getSubject().setReference(pid0);
obs.getCode().addCoding().setCode("2345-7").setSystem("http://loinc.org");
obs.setValue(new StringDt("150"));
oid3 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
ourLog.info("Observation: \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
{
Observation obs = new Observation();
obs.addIdentifier().setSystem("urn:system").setValue("FOO");
obs.getSubject().setReference(pid0);
obs.getCode().addCoding().setCode("2345-7").setSystem("http://loinc.org");
obs.setValue(new StringDt("250"));
oid4 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
ourLog.info("Observation: \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
SearchParameterMap pm = new SearchParameterMap();
pm.setSort(new SortSpec(Observation.SP_CODE_VALUE_CONCEPT));
try {
myObservationDao.search(pm).size();
fail();
} catch (InvalidRequestException e) {
assertEquals("This server does not support _sort specifications of type COMPOSITE - Can't serve _sort=code-value-concept", e.getMessage());
}
pm.setSort(new SortSpec(Observation.SP_CODE_VALUE_STRING));
IBundleProvider found = myObservationDao.search(pm);
List<IIdType> list = toUnqualifiedVersionlessIds(found);
assertEquals(4, list.size());
assertEquals(oid3, list.get(0));
assertEquals(oid1, list.get(1));
assertEquals(oid4, list.get(2));
assertEquals(oid2, list.get(3));
}
@Test
public void testSortByDate() {
Patient p = new Patient();

View File

@ -30,6 +30,7 @@ import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import com.google.common.collect.Lists;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.RandomStringUtils;
@ -2551,18 +2552,78 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
@Test()
public void testSortByComposite() {
Observation o = new Observation();
o.getCode().setText("testSortByComposite");
myObservationDao.create(o, mySrd);
IIdType pid0;
IIdType oid1;
IIdType oid2;
IIdType oid3;
IIdType oid4;
{
Patient patient = new Patient();
patient.addIdentifier().setSystem("urn:system").setValue("001");
patient.addName().setFamily("Tester").addGiven("Joe");
pid0 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless();
}
{
Observation obs = new Observation();
obs.addIdentifier().setSystem("urn:system").setValue("FOO");
obs.getSubject().setReferenceElement(pid0);
obs.getCode().addCoding().setCode("2345-7").setSystem("http://loinc.org");
obs.setValue(new StringType("200"));
oid1 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
ourLog.info("Observation: \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
{
Observation obs = new Observation();
obs.addIdentifier().setSystem("urn:system").setValue("FOO");
obs.getSubject().setReferenceElement(pid0);
obs.getCode().addCoding().setCode("2345-7").setSystem("http://loinc.org");
obs.setValue(new StringType("300"));
oid2 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
ourLog.info("Observation: \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
{
Observation obs = new Observation();
obs.addIdentifier().setSystem("urn:system").setValue("FOO");
obs.getSubject().setReferenceElement(pid0);
obs.getCode().addCoding().setCode("2345-7").setSystem("http://loinc.org");
obs.setValue(new StringType("150"));
oid3 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
ourLog.info("Observation: \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
{
Observation obs = new Observation();
obs.addIdentifier().setSystem("urn:system").setValue("FOO");
obs.getSubject().setReferenceElement(pid0);
obs.getCode().addCoding().setCode("2345-7").setSystem("http://loinc.org");
obs.setValue(new StringType("250"));
oid4 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
ourLog.info("Observation: \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
SearchParameterMap pm = new SearchParameterMap();
pm.setSort(new SortSpec(Observation.SP_CODE_VALUE_CONCEPT));
try {
myObservationDao.search(pm).size();
fail();
} catch (InvalidRequestException e) {
assertEquals("This server does not support _sort specifications of type COMPOSITE - Can't serve _sort=code-value-concept", e.getMessage());
}
pm.setSort(new SortSpec(Observation.SP_CODE_VALUE_STRING));
IBundleProvider found = myObservationDao.search(pm);
List<IIdType> list = toUnqualifiedVersionlessIds(found);
assertEquals(4, list.size());
assertEquals(oid3, list.get(0));
assertEquals(oid1, list.get(1));
assertEquals(oid4, list.get(2));
assertEquals(oid2, list.get(3));
}
@Test

View File

@ -2979,21 +2979,82 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
assertTrue(next.getResource().getIdElement().hasIdPart());
}
}
@Test()
public void testSortByComposite() {
Observation o = new Observation();
o.getCode().setText("testSortByComposite");
myObservationDao.create(o, mySrd);
IIdType pid0;
IIdType oid1;
IIdType oid2;
IIdType oid3;
IIdType oid4;
{
Patient patient = new Patient();
patient.addIdentifier().setSystem("urn:system").setValue("001");
patient.addName().setFamily("Tester").addGiven("Joe");
pid0 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless();
}
{
Observation obs = new Observation();
obs.addIdentifier().setSystem("urn:system").setValue("FOO");
obs.getSubject().setReferenceElement(pid0);
obs.getCode().addCoding().setCode("2345-7").setSystem("http://loinc.org");
obs.setValue(new StringType("200"));
oid1 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
ourLog.info("Observation: \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
{
Observation obs = new Observation();
obs.addIdentifier().setSystem("urn:system").setValue("FOO");
obs.getSubject().setReferenceElement(pid0);
obs.getCode().addCoding().setCode("2345-7").setSystem("http://loinc.org");
obs.setValue(new StringType("300"));
oid2 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
ourLog.info("Observation: \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
{
Observation obs = new Observation();
obs.addIdentifier().setSystem("urn:system").setValue("FOO");
obs.getSubject().setReferenceElement(pid0);
obs.getCode().addCoding().setCode("2345-7").setSystem("http://loinc.org");
obs.setValue(new StringType("150"));
oid3 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
ourLog.info("Observation: \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
{
Observation obs = new Observation();
obs.addIdentifier().setSystem("urn:system").setValue("FOO");
obs.getSubject().setReferenceElement(pid0);
obs.getCode().addCoding().setCode("2345-7").setSystem("http://loinc.org");
obs.setValue(new StringType("250"));
oid4 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
ourLog.info("Observation: \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
SearchParameterMap pm = new SearchParameterMap();
pm.setSort(new SortSpec(Observation.SP_CODE_VALUE_CONCEPT));
try {
myObservationDao.search(pm).size();
fail();
} catch (InvalidRequestException e) {
assertEquals("This server does not support _sort specifications of type COMPOSITE - Can't serve _sort=code-value-concept", e.getMessage());
}
pm.setSort(new SortSpec(Observation.SP_CODE_VALUE_STRING));
IBundleProvider found = myObservationDao.search(pm);
List<IIdType> list = toUnqualifiedVersionlessIds(found);
assertEquals(4, list.size());
assertEquals(oid3, list.get(0));
assertEquals(oid1, list.get(1));
assertEquals(oid4, list.get(2));
assertEquals(oid2, list.get(3));
}
@Test

View File

@ -35,12 +35,9 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.model.dstu2.resource.SearchParameter;
import ca.uhn.fhir.model.dstu2.valueset.XPathUsageTypeEnum;
import ca.uhn.fhir.model.primitive.IntegerDt;
import ca.uhn.fhir.rest.api.SearchTotalModeEnum;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.gclient.NumberClientParam;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
@ -53,11 +50,9 @@ import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.hl7.fhir.instance.model.api.IBaseBundle;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
@ -74,6 +69,7 @@ import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
import ca.uhn.fhir.model.dstu2.composite.MetaDt;
import ca.uhn.fhir.model.dstu2.composite.PeriodDt;
import ca.uhn.fhir.model.dstu2.composite.QuantityDt;
import ca.uhn.fhir.model.dstu2.composite.ResourceReferenceDt;
import ca.uhn.fhir.model.dstu2.resource.BaseResource;
import ca.uhn.fhir.model.dstu2.resource.Basic;
@ -131,7 +127,6 @@ import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import ca.uhn.fhir.util.BundleUtil;
import ca.uhn.fhir.util.StopWatch;
import ca.uhn.fhir.util.TestUtil;
import ca.uhn.fhir.util.UrlUtil;
public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
@ -2185,23 +2180,86 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
}
@Test
public void testSearchWithInvalidSort() {
try {
Observation o = new Observation();
o.getCode().setText("testSearchWithInvalidSort");
myObservationDao.create(o, mySrd);
IBaseBundle bundle = ourClient
.search()
.forResource(Observation.class)
.sort().ascending(Observation.CODE_VALUE_QUANTITY) // composite sort not supported yet
.prettyPrint()
.execute();
fail();
} catch (InvalidRequestException e) {
assertEquals("HTTP 400 Bad Request: This server does not support _sort specifications of type COMPOSITE - Can't serve _sort=code-value-quantity", e.getMessage());
public void testSearchWithCompositeSortWith_CodeValueQuantity() throws IOException {
IIdType pid0;
IIdType oid1;
IIdType oid2;
IIdType oid3;
IIdType oid4;
{
Patient patient = new Patient();
patient.addIdentifier().setSystem("urn:system").setValue("001");
patient.addName().addFamily("Tester").addGiven("Joe");
pid0 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless();
}
{
Observation obs = new Observation();
obs.addIdentifier().setSystem("urn:system").setValue("FOO");
obs.getSubject().setReference(pid0);
obs.getCode().addCoding().setCode("2345-7").setSystem("http://loinc.org");
obs.setValue(new QuantityDt().setValue(200));
oid1 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
ourLog.info("Observation: \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
{
Observation obs = new Observation();
obs.addIdentifier().setSystem("urn:system").setValue("FOO");
obs.getSubject().setReference(pid0);
obs.getCode().addCoding().setCode("2345-7").setSystem("http://loinc.org");
obs.setValue(new QuantityDt().setValue(300));
oid2 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
ourLog.info("Observation: \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
{
Observation obs = new Observation();
obs.addIdentifier().setSystem("urn:system").setValue("FOO");
obs.getSubject().setReference(pid0);
obs.getCode().addCoding().setCode("2345-7").setSystem("http://loinc.org");
obs.setValue(new QuantityDt().setValue(150));
oid3 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
ourLog.info("Observation: \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
{
Observation obs = new Observation();
obs.addIdentifier().setSystem("urn:system").setValue("FOO");
obs.getSubject().setReference(pid0);
obs.getCode().addCoding().setCode("2345-7").setSystem("http://loinc.org");
obs.setValue(new QuantityDt().setValue(250));
oid4 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
ourLog.info("Observation: \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
String uri = ourServerBase + "/Observation?_sort=code-value-quantity";
Bundle found;
HttpGet get = new HttpGet(uri);
try (CloseableHttpResponse resp = ourHttpClient.execute(get)) {
String output = IOUtils.toString(resp.getEntity().getContent(), Charsets.UTF_8);
found = myFhirCtx.newXmlParser().parseResource(Bundle.class, output);
}
ourLog.info("Bundle: \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(found));
List<IIdType> list = toUnqualifiedVersionlessIds(found);
assertEquals(4, found.getEntry().size());
assertEquals(oid3, list.get(0));
assertEquals(oid1, list.get(1));
assertEquals(oid4, list.get(2));
assertEquals(oid2, list.get(3));
}
@Test
public void testSearchWithMissing() {
ourLog.info("Starting testSearchWithMissing");

View File

@ -3412,24 +3412,87 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
}
@Test
public void testSearchWithInvalidSort() {
try {
Observation o = new Observation();
o.getCode().setText("testSearchWithInvalidSort");
myObservationDao.create(o, mySrd);
ourClient
.search()
.forResource(Observation.class)
.sort().ascending(Observation.CODE_VALUE_QUANTITY) // composite sort not supported yet
.prettyPrint()
.returnBundle(Bundle.class)
.execute();
fail();
} catch (InvalidRequestException e) {
assertEquals("HTTP 400 Bad Request: This server does not support _sort specifications of type COMPOSITE - Can't serve _sort=code-value-quantity", e.getMessage());
public void testSearchWithCompositeSort_CodeValueDate() throws IOException {
IIdType pid0;
IIdType oid1;
IIdType oid2;
IIdType oid3;
IIdType oid4;
{
Patient patient = new Patient();
patient.addIdentifier().setSystem("urn:system").setValue("001");
patient.addName().setFamily("Tester").addGiven("Joe");
pid0 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless();
}
{
Observation obs = new Observation();
obs.addIdentifier().setSystem("urn:system").setValue("FOO");
obs.getSubject().setReferenceElement(pid0);
obs.getCode().addCoding().setCode("2345-7").setSystem("http://loinc.org");
obs.setValue(new DateTimeType("2020-02-01"));
oid1 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
ourLog.info("Observation: \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
{
Observation obs = new Observation();
obs.addIdentifier().setSystem("urn:system").setValue("FOO");
obs.getSubject().setReferenceElement(pid0);
obs.getCode().addCoding().setCode("2345-7").setSystem("http://loinc.org");
obs.setValue(new DateTimeType("2020-04-01"));
oid2 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
ourLog.info("Observation: \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
{
Observation obs = new Observation();
obs.addIdentifier().setSystem("urn:system").setValue("FOO");
obs.getSubject().setReferenceElement(pid0);
obs.getCode().addCoding().setCode("2345-7").setSystem("http://loinc.org");
obs.setValue(new DateTimeType("2020-01-01"));
oid3 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
ourLog.info("Observation: \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
{
Observation obs = new Observation();
obs.addIdentifier().setSystem("urn:system").setValue("FOO");
obs.getSubject().setReferenceElement(pid0);
obs.getCode().addCoding().setCode("2345-7").setSystem("http://loinc.org");
obs.setValue(new DateTimeType("2020-03-01"));
oid4 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
ourLog.info("Observation: \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
String uri = ourServerBase + "/Observation?_sort=code-value-date";
Bundle found;
HttpGet get = new HttpGet(uri);
try (CloseableHttpResponse resp = ourHttpClient.execute(get)) {
String output = IOUtils.toString(resp.getEntity().getContent(), Charsets.UTF_8);
found = myFhirCtx.newXmlParser().parseResource(Bundle.class, output);
}
ourLog.info("Bundle: \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(found));
List<IIdType> list = toUnqualifiedVersionlessIds(found);
assertEquals(4, found.getEntry().size());
assertEquals(oid3, list.get(0));
assertEquals(oid1, list.get(1));
assertEquals(oid4, list.get(2));
assertEquals(oid2, list.get(3));
}
@Test
public void testSearchWithMissing() {
ourLog.info("Starting testSearchWithMissing");

View File

@ -75,6 +75,7 @@ import org.hl7.fhir.r4.model.Bundle.SearchEntryMode;
import org.hl7.fhir.r4.model.CarePlan;
import org.hl7.fhir.r4.model.CodeSystem;
import org.hl7.fhir.r4.model.CodeType;
import org.hl7.fhir.r4.model.CodeableConcept;
import org.hl7.fhir.r4.model.Coding;
import org.hl7.fhir.r4.model.Condition;
import org.hl7.fhir.r4.model.DateTimeType;
@ -104,6 +105,7 @@ import org.hl7.fhir.r4.model.MolecularSequence;
import org.hl7.fhir.r4.model.Narrative;
import org.hl7.fhir.r4.model.Narrative.NarrativeStatus;
import org.hl7.fhir.r4.model.Observation;
import org.hl7.fhir.r4.model.Observation.ObservationComponentComponent;
import org.hl7.fhir.r4.model.Observation.ObservationStatus;
import org.hl7.fhir.r4.model.OperationOutcome;
import org.hl7.fhir.r4.model.Organization;
@ -4546,24 +4548,183 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
}
@Test
public void testSearchWithInvalidSort() {
try {
Observation o = new Observation();
o.getCode().setText("testSearchWithInvalidSort");
myObservationDao.create(o, mySrd);
myClient
.search()
.forResource(Observation.class)
.sort().ascending(Observation.CODE_VALUE_QUANTITY) // composite sort not supported yet
.prettyPrint()
.returnBundle(Bundle.class)
.execute();
fail();
} catch (InvalidRequestException e) {
assertEquals("HTTP 400 Bad Request: This server does not support _sort specifications of type COMPOSITE - Can't serve _sort=code-value-quantity", e.getMessage());
public void testSearchWithCompositeSortWith_CodeValueQuantity() throws IOException {
IIdType pid0;
IIdType oid1;
IIdType oid2;
IIdType oid3;
IIdType oid4;
{
Patient patient = new Patient();
patient.addIdentifier().setSystem("urn:system").setValue("001");
patient.addName().setFamily("Tester").addGiven("Joe");
pid0 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless();
}
{
Observation obs = new Observation();
obs.addIdentifier().setSystem("urn:system").setValue("FOO");
obs.getSubject().setReferenceElement(pid0);
obs.getCode().addCoding().setCode("2345-7").setSystem("http://loinc.org");
obs.setValue(new Quantity().setValue(200));
oid1 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
ourLog.info("Observation: \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
{
Observation obs = new Observation();
obs.addIdentifier().setSystem("urn:system").setValue("FOO");
obs.getSubject().setReferenceElement(pid0);
obs.getCode().addCoding().setCode("2345-7").setSystem("http://loinc.org");
obs.setValue(new Quantity().setValue(300));
oid2 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
ourLog.info("Observation: \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
{
Observation obs = new Observation();
obs.addIdentifier().setSystem("urn:system").setValue("FOO");
obs.getSubject().setReferenceElement(pid0);
obs.getCode().addCoding().setCode("2345-7").setSystem("http://loinc.org");
obs.setValue(new Quantity().setValue(150));
oid3 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
ourLog.info("Observation: \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
{
Observation obs = new Observation();
obs.addIdentifier().setSystem("urn:system").setValue("FOO");
obs.getSubject().setReferenceElement(pid0);
obs.getCode().addCoding().setCode("2345-7").setSystem("http://loinc.org");
obs.setValue(new Quantity().setValue(250));
oid4 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
ourLog.info("Observation: \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
String uri = ourServerBase + "/Observation?_sort=code-value-quantity";
Bundle found;
HttpGet get = new HttpGet(uri);
try (CloseableHttpResponse resp = ourHttpClient.execute(get)) {
String output = IOUtils.toString(resp.getEntity().getContent(), Charsets.UTF_8);
found = myFhirCtx.newXmlParser().parseResource(Bundle.class, output);
}
ourLog.info("Bundle: \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(found));
List<IIdType> list = toUnqualifiedVersionlessIds(found);
assertEquals(4, found.getEntry().size());
assertEquals(oid3, list.get(0));
assertEquals(oid1, list.get(1));
assertEquals(oid4, list.get(2));
assertEquals(oid2, list.get(3));
}
@Test
public void testSearchWithCompositeSortWith_CompCodeValueQuantity() throws IOException {
IIdType pid0;
IIdType oid1;
IIdType oid2;
IIdType oid3;
IIdType oid4;
{
Patient patient = new Patient();
patient.addIdentifier().setSystem("urn:system").setValue("001");
patient.addName().setFamily("Tester").addGiven("Joe");
pid0 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless();
}
{
Observation obs = new Observation();
obs.addIdentifier().setSystem("urn:system").setValue("FOO");
obs.getSubject().setReferenceElement(pid0);
ObservationComponentComponent comp = obs.addComponent();
CodeableConcept cc = new CodeableConcept();
cc.addCoding().setCode("2345-7").setSystem("http://loinc.org");
comp.setCode(cc);
comp.setValue(new Quantity().setValue(200));
oid1 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
ourLog.info("Observation: \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
{
Observation obs = new Observation();
obs.addIdentifier().setSystem("urn:system").setValue("FOO");
obs.getSubject().setReferenceElement(pid0);
ObservationComponentComponent comp = obs.addComponent();
CodeableConcept cc = new CodeableConcept();
cc.addCoding().setCode("2345-7").setSystem("http://loinc.org");
comp.setCode(cc);
comp.setValue(new Quantity().setValue(300));
oid2 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
ourLog.info("Observation: \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
{
Observation obs = new Observation();
obs.addIdentifier().setSystem("urn:system").setValue("FOO");
obs.getSubject().setReferenceElement(pid0);
ObservationComponentComponent comp = obs.addComponent();
CodeableConcept cc = new CodeableConcept();
cc.addCoding().setCode("2345-7").setSystem("http://loinc.org");
comp.setCode(cc);
comp.setValue(new Quantity().setValue(150));
oid3 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
ourLog.info("Observation: \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
{
Observation obs = new Observation();
obs.addIdentifier().setSystem("urn:system").setValue("FOO");
obs.getSubject().setReferenceElement(pid0);
ObservationComponentComponent comp = obs.addComponent();
CodeableConcept cc = new CodeableConcept();
cc.addCoding().setCode("2345-7").setSystem("http://loinc.org");
comp.setCode(cc);
comp.setValue(new Quantity().setValue(250));
oid4 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
ourLog.info("Observation: \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
}
String uri = ourServerBase + "/Observation?_sort=combo-code-value-quantity";
Bundle found;
HttpGet get = new HttpGet(uri);
try (CloseableHttpResponse resp = ourHttpClient.execute(get)) {
String output = IOUtils.toString(resp.getEntity().getContent(), Charsets.UTF_8);
found = myFhirCtx.newXmlParser().parseResource(Bundle.class, output);
}
ourLog.info("Bundle: \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(found));
List<IIdType> list = toUnqualifiedVersionlessIds(found);
assertEquals(4, found.getEntry().size());
assertEquals(oid3, list.get(0));
assertEquals(oid1, list.get(1));
assertEquals(oid4, list.get(2));
assertEquals(oid2, list.get(3));
}
@Test
public void testSearchWithMissing() {
myDaoConfig.setIndexMissingFields(DaoConfig.IndexEnabledEnum.ENABLED);