Enable filtering $lastn operation by Observation effective date.

This commit is contained in:
ianmarshall 2020-06-02 16:37:07 -04:00
parent 0317ee0139
commit 2e709a50c0
8 changed files with 260 additions and 41 deletions

View File

@ -60,6 +60,10 @@ public class BaseJpaResourceProviderObservationDstu3 extends JpaResourceProvider
@OperationParam(name="code")
TokenAndListParam theCode,
@Description(shortDefinition="The effective date of the observation")
@OperationParam(name="date")
DateAndListParam theDate,
@Description(shortDefinition="The subject that the observation is about (if patient)")
@OperationParam(name="patient")
ReferenceAndListParam thePatient,
@ -78,11 +82,12 @@ public class BaseJpaResourceProviderObservationDstu3 extends JpaResourceProvider
SearchParameterMap paramMap = new SearchParameterMap();
paramMap.add(Observation.SP_CATEGORY, theCategory);
paramMap.add(Observation.SP_CODE, theCode);
paramMap.add(Observation.SP_DATE, theDate);
if (thePatient != null) {
paramMap.add("patient", thePatient);
paramMap.add(Observation.SP_PATIENT, thePatient);
}
if (theSubject != null) {
paramMap.add("subject", theSubject);
paramMap.add(Observation.SP_SUBJECT, theSubject);
}
paramMap.setLastNMax(theMax.getValue());
if (theCount != null) {

View File

@ -59,6 +59,10 @@ public class BaseJpaResourceProviderObservationR4 extends JpaResourceProviderR4<
@OperationParam(name="code")
TokenAndListParam theCode,
@Description(shortDefinition="The effective date of the observation")
@OperationParam(name="date")
DateAndListParam theDate,
@Description(shortDefinition="The subject that the observation is about (if patient)")
@OperationParam(name="patient")
ReferenceAndListParam thePatient,
@ -77,6 +81,7 @@ public class BaseJpaResourceProviderObservationR4 extends JpaResourceProviderR4<
SearchParameterMap paramMap = new SearchParameterMap();
paramMap.add(Observation.SP_CATEGORY, theCategory);
paramMap.add(Observation.SP_CODE, theCode);
paramMap.add(Observation.SP_DATE, theDate);
if (thePatient != null) {
paramMap.add(Observation.SP_PATIENT, thePatient);
}

View File

@ -60,6 +60,10 @@ public class BaseJpaResourceProviderObservationR5 extends JpaResourceProviderR5<
@OperationParam(name="code")
TokenAndListParam theCode,
@Description(shortDefinition="The effective date of the observation")
@OperationParam(name="date")
DateAndListParam theDate,
@Description(shortDefinition="The subject that the observation is about (if patient)")
@OperationParam(name="patient")
ReferenceAndListParam thePatient,
@ -78,6 +82,7 @@ public class BaseJpaResourceProviderObservationR5 extends JpaResourceProviderR5<
SearchParameterMap paramMap = new SearchParameterMap();
paramMap.add(Observation.SP_CATEGORY, theCategory);
paramMap.add(Observation.SP_CODE, theCode);
paramMap.add(Observation.SP_DATE, theDate);
if (thePatient != null) {
paramMap.add(Observation.SP_PATIENT, thePatient);
}

View File

@ -7,6 +7,8 @@ import ca.uhn.fhir.jpa.search.lastn.json.ObservationJson;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.jpa.searchparam.util.LastNParameterHelper;
import ca.uhn.fhir.model.api.IQueryParameterType;
import ca.uhn.fhir.rest.param.DateParam;
import ca.uhn.fhir.rest.param.ParamPrefixEnum;
import ca.uhn.fhir.rest.param.ReferenceParam;
import ca.uhn.fhir.rest.param.TokenParam;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
@ -25,7 +27,9 @@ import org.shadehapi.elasticsearch.client.RequestOptions;
import org.shadehapi.elasticsearch.client.RestHighLevelClient;
import org.shadehapi.elasticsearch.common.xcontent.XContentType;
import org.shadehapi.elasticsearch.index.query.BoolQueryBuilder;
import org.shadehapi.elasticsearch.index.query.MatchQueryBuilder;
import org.shadehapi.elasticsearch.index.query.QueryBuilders;
import org.shadehapi.elasticsearch.index.query.RangeQueryBuilder;
import org.shadehapi.elasticsearch.index.reindex.DeleteByQueryRequest;
import org.shadehapi.elasticsearch.search.SearchHit;
import org.shadehapi.elasticsearch.search.SearchHits;
@ -321,6 +325,7 @@ public class ElasticsearchSvcImpl implements IElasticsearchSvc {
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
addCategoriesCriteria(boolQueryBuilder, theSearchParameterMap, theFhirContext);
addObservationCodeCriteria(boolQueryBuilder, theSearchParameterMap, theFhirContext);
addDateCriteria(boolQueryBuilder, theSearchParameterMap, theFhirContext);
searchSourceBuilder.query(boolQueryBuilder);
}
searchSourceBuilder.size(0);
@ -341,6 +346,7 @@ public class ElasticsearchSvcImpl implements IElasticsearchSvc {
boolQueryBuilder.must(QueryBuilders.termQuery("subject", theSubjectParam));
addCategoriesCriteria(boolQueryBuilder, theSearchParameterMap, theFhirContext);
addObservationCodeCriteria(boolQueryBuilder, theSearchParameterMap, theFhirContext);
addDateCriteria(boolQueryBuilder, theSearchParameterMap, theFhirContext);
searchSourceBuilder.query(boolQueryBuilder);
searchSourceBuilder.size(0);
@ -492,6 +498,41 @@ public class ElasticsearchSvcImpl implements IElasticsearchSvc {
}
private void addDateCriteria(BoolQueryBuilder theBoolQueryBuilder, SearchParameterMap theSearchParameterMap, FhirContext theFhirContext) {
String dateParamName = LastNParameterHelper.getEffectiveParamName(theFhirContext);
if (theSearchParameterMap.containsKey(dateParamName)) {
List<List<IQueryParameterType>> andOrParams = theSearchParameterMap.get(dateParamName);
for (List<? extends IQueryParameterType> nextAnd : andOrParams) {
BoolQueryBuilder myDateBoolQueryBuilder = new BoolQueryBuilder();
for (IQueryParameterType nextOr : nextAnd) {
if (nextOr instanceof DateParam) {
DateParam myDate = (DateParam) nextOr;
createDateCriteria(myDate, myDateBoolQueryBuilder);
}
}
theBoolQueryBuilder.must(myDateBoolQueryBuilder);
}
}
}
private void createDateCriteria(DateParam theDate, BoolQueryBuilder theBoolQueryBuilder) {
Long dateInstant = theDate.getValue().getTime();
RangeQueryBuilder myRangeQueryBuilder = new RangeQueryBuilder("effectivedtm");
ParamPrefixEnum prefix = theDate.getPrefix();
if (prefix == ParamPrefixEnum.GREATERTHAN || prefix == ParamPrefixEnum.STARTS_AFTER) {
theBoolQueryBuilder.should(myRangeQueryBuilder.gt(dateInstant));
} else if (prefix == ParamPrefixEnum.LESSTHAN || prefix == ParamPrefixEnum.ENDS_BEFORE) {
theBoolQueryBuilder.should(myRangeQueryBuilder.lt(dateInstant));
} else if (prefix == ParamPrefixEnum.LESSTHAN_OR_EQUALS) {
theBoolQueryBuilder.should(myRangeQueryBuilder.lte(dateInstant));
} else if (prefix == ParamPrefixEnum.GREATERTHAN_OR_EQUALS) {
theBoolQueryBuilder.should(myRangeQueryBuilder.gte(dateInstant));
} else {
theBoolQueryBuilder.should(new MatchQueryBuilder("effectivedtm", dateInstant));
}
}
@VisibleForTesting
List<ObservationJson> executeLastNWithAllFields(SearchParameterMap theSearchParameterMap, FhirContext theFhirContext) {
return buildAndExecuteSearch(theSearchParameterMap, theFhirContext, null, t -> t, 100);

View File

@ -8,6 +8,10 @@ import ca.uhn.fhir.jpa.config.TestR4ConfigWithElasticsearchClient;
import ca.uhn.fhir.jpa.dao.BaseJpaTest;
import ca.uhn.fhir.jpa.dao.SearchBuilder;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.rest.param.DateAndListParam;
import ca.uhn.fhir.rest.param.DateOrListParam;
import ca.uhn.fhir.rest.param.DateParam;
import ca.uhn.fhir.rest.param.ParamPrefixEnum;
import ca.uhn.fhir.rest.param.ReferenceAndListParam;
import ca.uhn.fhir.rest.param.ReferenceOrListParam;
import ca.uhn.fhir.rest.param.ReferenceParam;
@ -105,6 +109,8 @@ public class BaseR4SearchLastN extends BaseJpaTest {
private static final Map<String, String> observationCodeMap = new HashMap<>();
private static final Map<String, Date> observationEffectiveMap = new HashMap<>();
private static Calendar observationDate = new GregorianCalendar();
@Before
public void beforeCreateTestPatientsAndObservations() {
// Using a static flag to ensure that test data and elasticsearch index is only created once.
@ -141,15 +147,13 @@ public class BaseR4SearchLastN extends BaseJpaTest {
private void createFiveObservationsForPatientCodeCategory(IIdType thePatientId, String theObservationCode, String theCategoryCode,
Integer theTimeOffset) {
Calendar observationDate = new GregorianCalendar();
for (int idx=0; idx<5; idx++ ) {
Observation obs = new Observation();
obs.getSubject().setReferenceElement(thePatientId);
obs.getCode().addCoding().setCode(theObservationCode).setSystem(codeSystem);
obs.setValue(new StringType(theObservationCode + "_0"));
observationDate.add(Calendar.HOUR, -theTimeOffset+idx);
Date effectiveDtm = observationDate.getTime();
Date effectiveDtm = new Date(observationDate.getTimeInMillis() - (3600*1000*(theTimeOffset+idx)));
obs.setEffective(new DateTimeType(effectiveDtm));
obs.getCategoryFirstRep().addCoding().setCode(theCategoryCode).setSystem(categorySystem);
String observationId = myObservationDao.create(obs, mockSrd()).getId().toUnqualifiedVersionless().getValue();
@ -535,6 +539,53 @@ public class BaseR4SearchLastN extends BaseJpaTest {
return new TokenAndListParam().addAnd(myTokenOrListParam);
}
@Test
public void testLastNSingleDate() {
SearchParameterMap params = new SearchParameterMap();
ReferenceParam subjectParam = new ReferenceParam("Patient", "", patient0Id.getValue());
params.add(Observation.SP_SUBJECT, buildReferenceAndListParam(subjectParam));
DateParam myDateParam = new DateParam(ParamPrefixEnum.LESSTHAN, new Date(observationDate.getTimeInMillis() - (3600*1000*9)));
params.add(Observation.SP_DATE, myDateParam);
List<String> sortedPatients = new ArrayList<>();
sortedPatients.add(patient0Id.getValue());
List<String> sortedObservationCodes = new ArrayList<>();
sortedObservationCodes.add(observationCd0);
sortedObservationCodes.add(observationCd1);
executeTestCase(params, sortedPatients,sortedObservationCodes, null,15);
}
@Test
public void testLastNMultipleDates() {
SearchParameterMap params = new SearchParameterMap();
ReferenceParam subjectParam = new ReferenceParam("Patient", "", patient0Id.getValue());
params.add(Observation.SP_SUBJECT, buildReferenceAndListParam(subjectParam));
DateParam lowDateParam = new DateParam(ParamPrefixEnum.LESSTHAN, new Date(observationDate.getTimeInMillis() - (3600*1000*(9))));
DateParam highDateParam = new DateParam(ParamPrefixEnum.GREATERTHAN, new Date(observationDate.getTimeInMillis() - (3600*1000*(15))));
DateAndListParam myDateAndListParam = new DateAndListParam();
myDateAndListParam.addAnd(new DateOrListParam().addOr(lowDateParam));
myDateAndListParam.addAnd(new DateOrListParam().addOr(highDateParam));
params.add(Observation.SP_DATE, myDateAndListParam);
List<String> sortedPatients = new ArrayList<>();
sortedPatients.add(patient0Id.getValue());
List<String> sortedObservationCodes = new ArrayList<>();
sortedObservationCodes.add(observationCd0);
sortedObservationCodes.add(observationCd1);
executeTestCase(params, sortedPatients,sortedObservationCodes, null,10);
}
@AfterClass
public static void afterClassClearContext() {
TestUtil.clearAllStaticFieldsForUnitTest();

View File

@ -33,10 +33,13 @@ public class LastNElasticsearchSvcMultipleObservationsIT {
private static ObjectMapper ourMapperNonPrettyPrint;
private static boolean indexLoaded = false;
private final Map<String, Map<String, List<Date>>> createdPatientObservationMap = new HashMap<>();
private FhirContext myFhirContext = FhirContext.forR4();
static private Calendar baseObservationDate = new GregorianCalendar();
@BeforeClass
public static void beforeClass() {
@ -48,13 +51,10 @@ public class LastNElasticsearchSvcMultipleObservationsIT {
@Before
public void before() throws IOException {
createMultiplePatientsAndObservations();
}
@After
public void after() throws IOException {
elasticsearchSvc.deleteAllDocuments(ElasticsearchSvcImpl.OBSERVATION_INDEX);
elasticsearchSvc.deleteAllDocuments(ElasticsearchSvcImpl.OBSERVATION_CODE_INDEX);
if (!indexLoaded) {
createMultiplePatientsAndObservations();
indexLoaded = true;
}
}
@Test
@ -248,27 +248,41 @@ public class LastNElasticsearchSvcMultipleObservationsIT {
@Test
public void testLastNNoMatchQueries() {
// Invalid Patient
ReferenceParam validPatientParam = new ReferenceParam("Patient", "", "9");
TokenParam validCategoryCodeParam = new TokenParam("http://mycodes.org/fhir/observation-category","test-heart-rate");
TokenParam validObservationCodeParam = new TokenParam("http://mycodes.org/fhir/observation-code", "test-code-1");
DateParam validDateParam = new DateParam(ParamPrefixEnum.EQUAL, new Date(baseObservationDate.getTimeInMillis() - (9*3600*1000)));
// Ensure that valid parameters are indeed valid
SearchParameterMap searchParameterMap = new SearchParameterMap();
ReferenceParam patientParam = new ReferenceParam("Patient", "", "10");
searchParameterMap.add(Observation.SP_PATIENT, buildReferenceAndListParam(patientParam));
TokenParam categoryParam = new TokenParam("http://mycodes.org/fhir/observation-category", "test-heart-rate");
searchParameterMap.add(Observation.SP_CATEGORY, buildTokenAndListParam(categoryParam));
TokenParam codeParam = new TokenParam("http://mycodes.org/fhir/observation-code", "test-code-1");
searchParameterMap.add(Observation.SP_CODE, buildTokenAndListParam(codeParam));
searchParameterMap.add(Observation.SP_PATIENT, buildReferenceAndListParam(validPatientParam));
searchParameterMap.add(Observation.SP_CATEGORY, buildTokenAndListParam(validCategoryCodeParam));
searchParameterMap.add(Observation.SP_CODE, buildTokenAndListParam(validObservationCodeParam));
searchParameterMap.add(Observation.SP_DATE, validDateParam);
searchParameterMap.setLastNMax(100);
List<String> observations = elasticsearchSvc.executeLastN(searchParameterMap, myFhirContext, 100);
assertEquals(1, observations.size());
// Invalid Patient
searchParameterMap = new SearchParameterMap();
ReferenceParam patientParam = new ReferenceParam("Patient", "", "10");
searchParameterMap.add(Observation.SP_PATIENT, buildReferenceAndListParam(patientParam));
searchParameterMap.add(Observation.SP_CATEGORY, buildTokenAndListParam(validCategoryCodeParam));
searchParameterMap.add(Observation.SP_CODE, buildTokenAndListParam(validObservationCodeParam));
searchParameterMap.add(Observation.SP_DATE, validDateParam);
searchParameterMap.setLastNMax(100);
observations = elasticsearchSvc.executeLastN(searchParameterMap, myFhirContext, 100);
assertEquals(0, observations.size());
// Invalid subject
searchParameterMap = new SearchParameterMap();
ReferenceParam subjectParam = new ReferenceParam("Patient", "", "10");
searchParameterMap.add(Observation.SP_SUBJECT, buildReferenceAndListParam(subjectParam));
categoryParam = new TokenParam("http://mycodes.org/fhir/observation-category", "test-heart-rate");
searchParameterMap.add(Observation.SP_CATEGORY, buildTokenAndListParam(categoryParam));
codeParam = new TokenParam("http://mycodes.org/fhir/observation-code", "test-code-1");
searchParameterMap.add(Observation.SP_CODE, buildTokenAndListParam(codeParam));
searchParameterMap.add(Observation.SP_SUBJECT, buildReferenceAndListParam(patientParam));
searchParameterMap.add(Observation.SP_CATEGORY, buildTokenAndListParam(validCategoryCodeParam));
searchParameterMap.add(Observation.SP_CODE, buildTokenAndListParam(validObservationCodeParam));
searchParameterMap.add(Observation.SP_DATE, validDateParam);
searchParameterMap.setLastNMax(100);
observations = elasticsearchSvc.executeLastN(searchParameterMap, myFhirContext, 100);
@ -276,12 +290,11 @@ public class LastNElasticsearchSvcMultipleObservationsIT {
// Invalid observation code
searchParameterMap = new SearchParameterMap();
subjectParam = new ReferenceParam("Patient", "", "9");
searchParameterMap.add(Observation.SP_SUBJECT, buildReferenceAndListParam(subjectParam));
categoryParam = new TokenParam("http://mycodes.org/fhir/observation-category", "test-heart-rate");
searchParameterMap.add(Observation.SP_CATEGORY, buildTokenAndListParam(categoryParam));
codeParam = new TokenParam("http://mycodes.org/fhir/observation-code", "test-code-999");
searchParameterMap.add(Observation.SP_SUBJECT, buildReferenceAndListParam(validPatientParam));
searchParameterMap.add(Observation.SP_CATEGORY, buildTokenAndListParam(validCategoryCodeParam));
TokenParam codeParam = new TokenParam("http://mycodes.org/fhir/observation-code", "test-code-999");
searchParameterMap.add(Observation.SP_CODE, buildTokenAndListParam(codeParam));
searchParameterMap.add(Observation.SP_DATE, validDateParam);
searchParameterMap.setLastNMax(100);
observations = elasticsearchSvc.executeLastN(searchParameterMap, myFhirContext, 100);
@ -289,17 +302,112 @@ public class LastNElasticsearchSvcMultipleObservationsIT {
// Invalid category code
searchParameterMap = new SearchParameterMap();
subjectParam = new ReferenceParam("Patient", "", "9");
searchParameterMap.add(Observation.SP_SUBJECT, buildReferenceAndListParam(subjectParam));
categoryParam = new TokenParam("http://mycodes.org/fhir/observation-category", "test-not-a-category");
searchParameterMap.add(Observation.SP_SUBJECT, buildReferenceAndListParam(validPatientParam));
TokenParam categoryParam = new TokenParam("http://mycodes.org/fhir/observation-category", "test-not-a-category");
searchParameterMap.add(Observation.SP_CATEGORY, buildTokenAndListParam(categoryParam));
codeParam = new TokenParam("http://mycodes.org/fhir/observation-code", "test-code-1");
searchParameterMap.add(Observation.SP_CODE, buildTokenAndListParam(codeParam));
searchParameterMap.add(Observation.SP_CODE, buildTokenAndListParam(validObservationCodeParam));
searchParameterMap.add(Observation.SP_DATE, validDateParam);
searchParameterMap.setLastNMax(100);
observations = elasticsearchSvc.executeLastN(searchParameterMap, myFhirContext, 100);
assertEquals(0, observations.size());
// Invalid date
searchParameterMap = new SearchParameterMap();
searchParameterMap.add(Observation.SP_SUBJECT, buildReferenceAndListParam(validPatientParam));
searchParameterMap.add(Observation.SP_CATEGORY, buildTokenAndListParam(validCategoryCodeParam));
searchParameterMap.add(Observation.SP_CODE, buildTokenAndListParam(validObservationCodeParam));
searchParameterMap.add(Observation.SP_DATE, new DateParam(ParamPrefixEnum.GREATERTHAN, baseObservationDate.getTime()));
searchParameterMap.setLastNMax(100);
observations = elasticsearchSvc.executeLastN(searchParameterMap, myFhirContext, 100);
assertEquals(0, observations.size());
}
@Test
public void testLastNEffectiveDates() {
Date highDate = new Date(baseObservationDate.getTimeInMillis() - (3600*1000));
Date lowDate = new Date(baseObservationDate.getTimeInMillis() - (10*3600*1000));
SearchParameterMap searchParameterMap = new SearchParameterMap();
ReferenceParam subjectParam = new ReferenceParam("Patient", "", "3");
searchParameterMap.add(Observation.SP_SUBJECT, buildReferenceAndListParam(subjectParam));
DateParam dateParam = new DateParam(ParamPrefixEnum.EQUAL, lowDate);
searchParameterMap.add(Observation.SP_DATE, dateParam);
searchParameterMap.setLastNMax(100);
List<String> observations = elasticsearchSvc.executeLastN(searchParameterMap, myFhirContext, 100);
assertEquals(1, observations.size());
searchParameterMap = new SearchParameterMap();
searchParameterMap.add(Observation.SP_SUBJECT, buildReferenceAndListParam(subjectParam));
dateParam = new DateParam(ParamPrefixEnum.GREATERTHAN_OR_EQUALS, lowDate);
searchParameterMap.add(Observation.SP_DATE, dateParam);
searchParameterMap.setLastNMax(100);
observations = elasticsearchSvc.executeLastN(searchParameterMap, myFhirContext, 100);
assertEquals(10, observations.size());
searchParameterMap = new SearchParameterMap();
searchParameterMap.add(Observation.SP_SUBJECT, buildReferenceAndListParam(subjectParam));
dateParam = new DateParam(ParamPrefixEnum.GREATERTHAN, lowDate);
searchParameterMap.add(Observation.SP_DATE, dateParam);
searchParameterMap.setLastNMax(100);
observations = elasticsearchSvc.executeLastN(searchParameterMap, myFhirContext, 100);
assertEquals(9, observations.size());
searchParameterMap = new SearchParameterMap();
searchParameterMap.add(Observation.SP_SUBJECT, buildReferenceAndListParam(subjectParam));
dateParam = new DateParam(ParamPrefixEnum.STARTS_AFTER, lowDate);
searchParameterMap.add(Observation.SP_DATE, dateParam);
searchParameterMap.setLastNMax(100);
observations = elasticsearchSvc.executeLastN(searchParameterMap, myFhirContext, 100);
assertEquals(9, observations.size());
searchParameterMap = new SearchParameterMap();
searchParameterMap.add(Observation.SP_SUBJECT, buildReferenceAndListParam(subjectParam));
dateParam = new DateParam(ParamPrefixEnum.LESSTHAN_OR_EQUALS, highDate);
searchParameterMap.add(Observation.SP_DATE, dateParam);
searchParameterMap.setLastNMax(100);
observations = elasticsearchSvc.executeLastN(searchParameterMap, myFhirContext, 100);
assertEquals(10, observations.size());
searchParameterMap = new SearchParameterMap();
searchParameterMap.add(Observation.SP_SUBJECT, buildReferenceAndListParam(subjectParam));
dateParam = new DateParam(ParamPrefixEnum.LESSTHAN, highDate);
searchParameterMap.add(Observation.SP_DATE, dateParam);
searchParameterMap.setLastNMax(100);
observations = elasticsearchSvc.executeLastN(searchParameterMap, myFhirContext, 100);
assertEquals(9, observations.size());
searchParameterMap = new SearchParameterMap();
searchParameterMap.add(Observation.SP_SUBJECT, buildReferenceAndListParam(subjectParam));
dateParam = new DateParam(ParamPrefixEnum.ENDS_BEFORE, highDate);
searchParameterMap.add(Observation.SP_DATE, dateParam);
searchParameterMap.setLastNMax(100);
observations = elasticsearchSvc.executeLastN(searchParameterMap, myFhirContext, 100);
assertEquals(9, observations.size());
searchParameterMap = new SearchParameterMap();
searchParameterMap.add(Observation.SP_SUBJECT, buildReferenceAndListParam(subjectParam));
DateParam startDateParam = new DateParam(ParamPrefixEnum.GREATERTHAN, new Date(baseObservationDate.getTimeInMillis() - (4*3600*1000)));
DateAndListParam dateAndListParam = new DateAndListParam();
dateAndListParam.addAnd(new DateOrListParam().addOr(startDateParam));
dateParam = new DateParam(ParamPrefixEnum.LESSTHAN_OR_EQUALS, highDate);
dateAndListParam.addAnd(new DateOrListParam().addOr(dateParam));
searchParameterMap.add(Observation.SP_DATE, dateAndListParam);
searchParameterMap.setLastNMax(100);
observations = elasticsearchSvc.executeLastN(searchParameterMap, myFhirContext, 100);
assertEquals(3, observations.size());
searchParameterMap = new SearchParameterMap();
searchParameterMap.add(Observation.SP_SUBJECT, buildReferenceAndListParam(subjectParam));
startDateParam = new DateParam(ParamPrefixEnum.GREATERTHAN, new Date(baseObservationDate.getTimeInMillis() - (4*3600*1000)));
searchParameterMap.add(Observation.SP_DATE, startDateParam);
dateParam = new DateParam(ParamPrefixEnum.LESSTHAN, lowDate);
searchParameterMap.add(Observation.SP_DATE, dateParam);
searchParameterMap.setLastNMax(100);
observations = elasticsearchSvc.executeLastN(searchParameterMap, myFhirContext, 100);
assertEquals(0, observations.size());
}
private void createMultiplePatientsAndObservations() throws IOException {
@ -359,9 +467,7 @@ public class LastNElasticsearchSvcMultipleObservationsIT {
assertTrue(elasticsearchSvc.performIndex(ElasticsearchSvcImpl.OBSERVATION_CODE_INDEX, codeableConceptId2, codeJson2Document, ElasticsearchSvcImpl.CODE_DOCUMENT_TYPE));
}
Calendar observationDate = new GregorianCalendar();
observationDate.add(Calendar.HOUR, -10 + entryCount);
Date effectiveDtm = observationDate.getTime();
Date effectiveDtm = new Date(baseObservationDate.getTimeInMillis() - ((10-entryCount)*3600*1000));
observationJson.setEffectiveDtm(effectiveDtm);
String observationDocument = ourMapperNonPrettyPrint.writeValueAsString(observationJson);

View File

@ -7,6 +7,8 @@ import ca.uhn.fhir.jpa.search.lastn.json.CodeJson;
import ca.uhn.fhir.jpa.search.lastn.json.ObservationJson;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.model.dstu2.resource.Observation;
import ca.uhn.fhir.rest.param.DateParam;
import ca.uhn.fhir.rest.param.ParamPrefixEnum;
import ca.uhn.fhir.rest.param.ReferenceAndListParam;
import ca.uhn.fhir.rest.param.ReferenceOrListParam;
import ca.uhn.fhir.rest.param.ReferenceParam;
@ -108,6 +110,7 @@ public class LastNElasticsearchSvcSingleObservationIT {
searchParameterMap.add(Observation.SP_CATEGORY, new TokenAndListParam().addAnd(new TokenOrListParam().addOr(categoryParam)));
TokenParam codeParam = new TokenParam(CODEFIRSTCODINGSYSTEM, CODEFIRSTCODINGCODE);
searchParameterMap.add(Observation.SP_CODE, new TokenAndListParam().addAnd(new TokenOrListParam().addOr(codeParam)));
searchParameterMap.add(Observation.SP_DATE, new DateParam(ParamPrefixEnum.EQUAL, EFFECTIVEDTM));
searchParameterMap.setLastNMax(3);

View File

@ -38,17 +38,20 @@ public class LastNParameterHelper {
private static boolean isLastNParameterDstu3(String theParamName) {
return (theParamName.equals(org.hl7.fhir.dstu3.model.Observation.SP_SUBJECT) || theParamName.equals(org.hl7.fhir.dstu3.model.Observation.SP_PATIENT)
|| theParamName.equals(org.hl7.fhir.dstu3.model.Observation.SP_CATEGORY) || theParamName.equals(org.hl7.fhir.r5.model.Observation.SP_CODE));
|| theParamName.equals(org.hl7.fhir.dstu3.model.Observation.SP_CATEGORY) || theParamName.equals(org.hl7.fhir.r5.model.Observation.SP_CODE))
|| theParamName.equals(org.hl7.fhir.dstu3.model.Observation.SP_DATE);
}
private static boolean isLastNParameterR4(String theParamName) {
return (theParamName.equals(org.hl7.fhir.r4.model.Observation.SP_SUBJECT) || theParamName.equals(org.hl7.fhir.r4.model.Observation.SP_PATIENT)
|| theParamName.equals(org.hl7.fhir.r4.model.Observation.SP_CATEGORY) || theParamName.equals(org.hl7.fhir.r4.model.Observation.SP_CODE));
|| theParamName.equals(org.hl7.fhir.r4.model.Observation.SP_CATEGORY) || theParamName.equals(org.hl7.fhir.r4.model.Observation.SP_CODE))
|| theParamName.equals(org.hl7.fhir.r4.model.Observation.SP_DATE);
}
private static boolean isLastNParameterR5(String theParamName) {
return (theParamName.equals(org.hl7.fhir.r5.model.Observation.SP_SUBJECT) || theParamName.equals(org.hl7.fhir.r5.model.Observation.SP_PATIENT)
|| theParamName.equals(org.hl7.fhir.r5.model.Observation.SP_CATEGORY) || theParamName.equals(org.hl7.fhir.r5.model.Observation.SP_CODE));
|| theParamName.equals(org.hl7.fhir.r5.model.Observation.SP_CATEGORY) || theParamName.equals(org.hl7.fhir.r5.model.Observation.SP_CODE))
|| theParamName.equals(org.hl7.fhir.r5.model.Observation.SP_DATE);
}
public static String getSubjectParamName(FhirContext theContext) {