Fixed sorting with chunked and paged queries.
This commit is contained in:
parent
529e1e1f5e
commit
6a27192a96
|
@ -585,6 +585,11 @@
|
|||
<version>1.0-SNAPSHOT</version>
|
||||
<classifier>shaded6</classifier>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<version>42.2.9</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
|
|
@ -21,7 +21,6 @@ package ca.uhn.fhir.jpa.dao;
|
|||
*/
|
||||
|
||||
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoObservation;
|
||||
import ca.uhn.fhir.jpa.search.lastn.IndexConstants;
|
||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||
import ca.uhn.fhir.rest.api.*;
|
||||
import ca.uhn.fhir.rest.api.server.*;
|
||||
|
@ -35,12 +34,18 @@ public abstract class BaseHapiFhirResourceDaoObservation<T extends IBaseResource
|
|||
}
|
||||
|
||||
theSearchParameterMap.setLastN(true);
|
||||
if (theSearchParameterMap.getSort() == null) {
|
||||
SortSpec effectiveDtm = new SortSpec("date").setOrder(SortOrderEnum.DESC);
|
||||
// TODO: Should probably remove these constants, maybe move this logic to the version-specific classes.
|
||||
SortSpec observationCode = new SortSpec(IndexConstants.CODE_SEARCH_PARAM).setOrder(SortOrderEnum.ASC).setChain(effectiveDtm);
|
||||
theSearchParameterMap.setSort(new SortSpec(IndexConstants.SUBJECT_SEARCH_PARAM).setOrder(SortOrderEnum.ASC).setChain(observationCode));
|
||||
SortSpec effectiveDtm = new SortSpec(getEffectiveParamName()).setOrder(SortOrderEnum.DESC);
|
||||
SortSpec observationCode = new SortSpec(getCodeParamName()).setOrder(SortOrderEnum.ASC).setChain(effectiveDtm);
|
||||
if(theSearchParameterMap.containsKey(getSubjectParamName()) || theSearchParameterMap.containsKey(getPatientParamName())) {
|
||||
theSearchParameterMap.setSort(new SortSpec(getSubjectParamName()).setOrder(SortOrderEnum.ASC).setChain(observationCode));
|
||||
} else {
|
||||
theSearchParameterMap.setSort(observationCode);
|
||||
}
|
||||
}
|
||||
|
||||
abstract protected String getEffectiveParamName();
|
||||
abstract protected String getCodeParamName();
|
||||
abstract protected String getSubjectParamName();
|
||||
abstract protected String getPatientParamName();
|
||||
|
||||
}
|
||||
|
|
|
@ -317,7 +317,7 @@ public class SearchBuilder implements ISearchBuilder {
|
|||
} else {
|
||||
throw new InvalidRequestException("Max parameter is required for $lastn operation");
|
||||
}
|
||||
List<String> lastnResourceIds = myIElasticsearchSvc.executeLastN(myParams, myMaxObservationsPerCode, theMaximumResults);
|
||||
List<String> lastnResourceIds = myIElasticsearchSvc.executeLastN(myParams, myContext, theMaximumResults);
|
||||
for (String lastnResourceId : lastnResourceIds) {
|
||||
pids.add(myIdHelperService.resolveResourcePersistentIds(myRequestPartitionId, myResourceName, lastnResourceId));
|
||||
}
|
||||
|
@ -422,52 +422,6 @@ public class SearchBuilder implements ISearchBuilder {
|
|||
searchForIdsWithAndOr(myParams, theRequest);
|
||||
}
|
||||
|
||||
/*
|
||||
* Fulltext or lastn search
|
||||
*/
|
||||
/* if (myParams.containsKey(Constants.PARAM_CONTENT) || myParams.containsKey(Constants.PARAM_TEXT) || myParams.isLastN()) {
|
||||
List<ResourcePersistentId> pids = new ArrayList<>();
|
||||
if (myParams.containsKey(Constants.PARAM_CONTENT) || myParams.containsKey(Constants.PARAM_TEXT)) {
|
||||
if (myFulltextSearchSvc == null) {
|
||||
if (myParams.containsKey(Constants.PARAM_TEXT)) {
|
||||
throw new InvalidRequestException("Fulltext search is not enabled on this service, can not process parameter: " + Constants.PARAM_TEXT);
|
||||
} else if (myParams.containsKey(Constants.PARAM_CONTENT)) {
|
||||
throw new InvalidRequestException("Fulltext search is not enabled on this service, can not process parameter: " + Constants.PARAM_CONTENT);
|
||||
}
|
||||
}
|
||||
|
||||
if (myParams.getEverythingMode() != null) {
|
||||
pids = myFulltextSearchSvc.everything(myResourceName, myParams, theRequest);
|
||||
} else {
|
||||
pids = myFulltextSearchSvc.search(myResourceName, myParams);
|
||||
}
|
||||
} else if (myParams.isLastN()) {
|
||||
if (myIElasticsearchSvc == null) {
|
||||
if (myParams.isLastN()) {
|
||||
throw new InvalidRequestException("LastN operation is not enabled on this service, can not process this request");
|
||||
}
|
||||
}
|
||||
Integer myMaxObservationsPerCode = null;
|
||||
if(myParams.getLastNMax() != null) {
|
||||
myMaxObservationsPerCode = myParams.getLastNMax();
|
||||
} else {
|
||||
throw new InvalidRequestException("Max parameter is required for $lastn operation");
|
||||
}
|
||||
List<String> lastnResourceIds = myIElasticsearchSvc.executeLastN(myParams, myMaxObservationsPerCode);
|
||||
for (String lastnResourceId : lastnResourceIds) {
|
||||
pids.add(myIdHelperService.resolveResourcePersistentIds(myRequestPartitionId, myResourceName, lastnResourceId));
|
||||
}
|
||||
// pids = normalizeIdListForLastNInClause(lastnResourceIds);
|
||||
}
|
||||
if (pids.isEmpty()) {
|
||||
// Will never match
|
||||
pids = Collections.singletonList(new ResourcePersistentId(-1L));
|
||||
}
|
||||
|
||||
myQueryRoot.addPredicate(myQueryRoot.get("myId").as(Long.class).in(ResourcePersistentId.toLongList(pids)));
|
||||
|
||||
}
|
||||
*/
|
||||
// Add PID list predicate for full text search and/or lastn operation
|
||||
if (thePidList != null && thePidList.size() > 0) {
|
||||
myQueryRoot.addPredicate(myQueryRoot.get("myId").as(Long.class).in(thePidList));
|
||||
|
|
|
@ -30,8 +30,6 @@ import ca.uhn.fhir.rest.api.Constants;
|
|||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import ca.uhn.fhir.rest.api.server.storage.TransactionDetails;
|
||||
import ca.uhn.fhir.rest.param.ReferenceAndListParam;
|
||||
import ca.uhn.fhir.rest.param.TokenAndListParam;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.dstu3.model.Observation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
@ -52,6 +50,26 @@ public class FhirResourceDaoObservationDstu3 extends BaseHapiFhirResourceDaoObse
|
|||
return mySearchCoordinatorSvc.registerSearch(this, theSearchParameterMap, getResourceName(), new CacheControlDirective().parse(theRequestDetails.getHeaders(Constants.HEADER_CACHE_CONTROL)), theRequestDetails);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getEffectiveParamName() {
|
||||
return Observation.SP_DATE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getCodeParamName() {
|
||||
return Observation.SP_CODE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getSubjectParamName() {
|
||||
return Observation.SP_SUBJECT;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getPatientParamName() {
|
||||
return Observation.SP_PATIENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceTable updateEntity(RequestDetails theRequest, IBaseResource theResource, IBasePersistedResource theEntity, Date theDeletedTimestampOrNull, boolean thePerformIndexing,
|
||||
boolean theUpdateVersion, TransactionDetails theTransactionDetails, boolean theForceUpdate, boolean theCreateNewHistoryEntry) {
|
||||
|
|
|
@ -57,6 +57,26 @@ public class FhirResourceDaoObservationR4 extends BaseHapiFhirResourceDaoObserva
|
|||
return mySearchCoordinatorSvc.registerSearch(this, theSearchParameterMap, getResourceName(), new CacheControlDirective().parse(theRequestDetails.getHeaders(Constants.HEADER_CACHE_CONTROL)), theRequestDetails);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getEffectiveParamName() {
|
||||
return Observation.SP_DATE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getCodeParamName() {
|
||||
return Observation.SP_CODE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getSubjectParamName() {
|
||||
return Observation.SP_SUBJECT;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getPatientParamName() {
|
||||
return Observation.SP_PATIENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceTable updateEntity(RequestDetails theRequest, IBaseResource theResource, IBasePersistedResource theEntity, Date theDeletedTimestampOrNull, boolean thePerformIndexing,
|
||||
boolean theUpdateVersion, TransactionDetails theTransactionDetails, boolean theForceUpdate, boolean theCreateNewHistoryEntry) {
|
||||
|
|
|
@ -30,8 +30,6 @@ import ca.uhn.fhir.rest.api.Constants;
|
|||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import ca.uhn.fhir.rest.api.server.storage.TransactionDetails;
|
||||
import ca.uhn.fhir.rest.param.ReferenceAndListParam;
|
||||
import ca.uhn.fhir.rest.param.TokenAndListParam;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.r5.model.Observation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
@ -52,6 +50,26 @@ public class FhirResourceDaoObservationR5 extends BaseHapiFhirResourceDaoObserva
|
|||
return mySearchCoordinatorSvc.registerSearch(this, theSearchParameterMap, getResourceName(), new CacheControlDirective().parse(theRequestDetails.getHeaders(Constants.HEADER_CACHE_CONTROL)), theRequestDetails);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getEffectiveParamName() {
|
||||
return Observation.SP_DATE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getCodeParamName() {
|
||||
return Observation.SP_CODE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getSubjectParamName() {
|
||||
return Observation.SP_SUBJECT;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getPatientParamName() {
|
||||
return Observation.SP_PATIENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceTable updateEntity(RequestDetails theRequest, IBaseResource theResource, IBasePersistedResource theEntity, Date theDeletedTimestampOrNull, boolean thePerformIndexing,
|
||||
boolean theUpdateVersion, TransactionDetails theTransactionDetails, boolean theForceUpdate, boolean theCreateNewHistoryEntry) {
|
||||
|
|
|
@ -70,10 +70,7 @@ public class BaseJpaResourceProviderObservationDstu3 extends JpaResourceProvider
|
|||
|
||||
@Description(shortDefinition="The maximum number of observations to return for each observation code")
|
||||
@OperationParam(name = "max", typeName = "integer", min = 0, max = 1)
|
||||
IPrimitiveType<Integer> theMax,
|
||||
|
||||
@Sort
|
||||
SortSpec theSort
|
||||
IPrimitiveType<Integer> theMax
|
||||
|
||||
) {
|
||||
startRequest(theServletRequest);
|
||||
|
@ -81,17 +78,17 @@ 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_PATIENT, thePatient);
|
||||
paramMap.add(Observation.SP_SUBJECT, theSubject);
|
||||
if (thePatient != null) {
|
||||
paramMap.add("patient", thePatient);
|
||||
}
|
||||
if (theSubject != null) {
|
||||
paramMap.add("subject", theSubject);
|
||||
}
|
||||
paramMap.setLastNMax(theMax.getValue());
|
||||
if (theCount != null) {
|
||||
paramMap.setCount(theCount.getValue());
|
||||
}
|
||||
|
||||
if (theSort != null) {
|
||||
paramMap.setSort(theSort);
|
||||
}
|
||||
|
||||
return ((IFhirResourceDaoObservation<Observation>) getDao()).observationsLastN(paramMap, theRequestDetails, theServletResponse);
|
||||
} finally {
|
||||
endRequest(theServletRequest);
|
||||
|
|
|
@ -69,28 +69,25 @@ public class BaseJpaResourceProviderObservationR4 extends JpaResourceProviderR4<
|
|||
|
||||
@Description(shortDefinition="The maximum number of observations to return for each observation code")
|
||||
@OperationParam(name = "max", typeName = "integer", min = 0, max = 1)
|
||||
IPrimitiveType<Integer> theMax,
|
||||
|
||||
@Sort
|
||||
SortSpec theSort
|
||||
IPrimitiveType<Integer> theMax
|
||||
|
||||
) {
|
||||
startRequest(theServletRequest);
|
||||
try {
|
||||
SearchParameterMap paramMap = new SearchParameterMap();
|
||||
paramMap.add("category", theCategory);
|
||||
paramMap.add("code", theCode);
|
||||
paramMap.add("patient", thePatient);
|
||||
paramMap.add("subject", theSubject);
|
||||
paramMap.add(Observation.SP_CATEGORY, theCategory);
|
||||
paramMap.add(Observation.SP_CODE, theCode);
|
||||
if (thePatient != null) {
|
||||
paramMap.add(Observation.SP_PATIENT, thePatient);
|
||||
}
|
||||
if (theSubject != null) {
|
||||
paramMap.add(Observation.SP_SUBJECT, theSubject);
|
||||
}
|
||||
paramMap.setLastNMax(theMax.getValue());
|
||||
if (theCount != null) {
|
||||
paramMap.setCount(theCount.getValue());
|
||||
}
|
||||
|
||||
if (theSort != null) {
|
||||
paramMap.setSort(theSort);
|
||||
}
|
||||
|
||||
return ((IFhirResourceDaoObservation<Observation>) getDao()).observationsLastN(paramMap, theRequestDetails, theServletResponse);
|
||||
} finally {
|
||||
endRequest(theServletRequest);
|
||||
|
|
|
@ -70,28 +70,25 @@ public class BaseJpaResourceProviderObservationR5 extends JpaResourceProviderR5<
|
|||
|
||||
@Description(shortDefinition="The maximum number of observations to return for each observation code")
|
||||
@OperationParam(name = "max", typeName = "integer", min = 0, max = 1)
|
||||
IPrimitiveType<Integer> theMax,
|
||||
|
||||
@Sort
|
||||
SortSpec theSort
|
||||
IPrimitiveType<Integer> theMax
|
||||
|
||||
) {
|
||||
startRequest(theServletRequest);
|
||||
try {
|
||||
SearchParameterMap paramMap = new SearchParameterMap();
|
||||
paramMap.add("category", theCategory);
|
||||
paramMap.add("code", theCode);
|
||||
paramMap.add("patient", thePatient);
|
||||
paramMap.add("subject", theSubject);
|
||||
paramMap.add(Observation.SP_CATEGORY, theCategory);
|
||||
paramMap.add(Observation.SP_CODE, theCode);
|
||||
if (thePatient != null) {
|
||||
paramMap.add(Observation.SP_PATIENT, thePatient);
|
||||
}
|
||||
if (theSubject != null) {
|
||||
paramMap.add(Observation.SP_SUBJECT, theSubject);
|
||||
}
|
||||
paramMap.setLastNMax(theMax.getValue());
|
||||
if (theCount != null) {
|
||||
paramMap.setCount(theCount.getValue());
|
||||
}
|
||||
|
||||
if (theSort != null) {
|
||||
paramMap.setSort(theSort);
|
||||
}
|
||||
|
||||
return ((IFhirResourceDaoObservation<Observation>) getDao()).observationsLastN(paramMap, theRequestDetails, theServletResponse);
|
||||
} finally {
|
||||
endRequest(theServletRequest);
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package ca.uhn.fhir.jpa.search.lastn;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
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.ReferenceParam;
|
||||
import ca.uhn.fhir.rest.param.TokenParam;
|
||||
|
@ -48,13 +50,18 @@ import static org.apache.commons.lang3.StringUtils.isBlank;
|
|||
|
||||
public class ElasticsearchSvcImpl implements IElasticsearchSvc {
|
||||
|
||||
public static final String OBSERVATION_INDEX = "observation_index";
|
||||
public static final String CODE_INDEX = "code_index";
|
||||
public static final String OBSERVATION_DOCUMENT_TYPE = "ca.uhn.fhir.jpa.dao.lastn.entity.ObservationIndexedSearchParamLastNEntity";
|
||||
public static final String CODE_DOCUMENT_TYPE = "ca.uhn.fhir.jpa.dao.lastn.entity.ObservationIndexedCodeCodeableConceptEntity";
|
||||
|
||||
private final RestHighLevelClient myRestHighLevelClient;
|
||||
|
||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
private final String GROUP_BY_SUBJECT = "group_by_subject";
|
||||
private final String GROUP_BY_SYSTEM = "group_by_system";
|
||||
private final String GROUP_BY_CODE = "group_by_code";
|
||||
private final String OBSERVATION_IDENTIFIER_FIELD_NAME = "identifier";
|
||||
|
||||
|
||||
public ElasticsearchSvcImpl(String theHostname, int thePort, String theUsername, String thePassword) {
|
||||
|
@ -69,7 +76,7 @@ public class ElasticsearchSvcImpl implements IElasticsearchSvc {
|
|||
}
|
||||
|
||||
private void createObservationIndexIfMissing() throws IOException {
|
||||
if (indexExists(IndexConstants.OBSERVATION_INDEX)) {
|
||||
if (indexExists(OBSERVATION_INDEX)) {
|
||||
return;
|
||||
}
|
||||
String observationMapping = "{\n" +
|
||||
|
@ -124,14 +131,14 @@ public class ElasticsearchSvcImpl implements IElasticsearchSvc {
|
|||
" }\n" +
|
||||
" }\n" +
|
||||
"}\n";
|
||||
if (!createIndex(IndexConstants.OBSERVATION_INDEX, observationMapping)) {
|
||||
if (!createIndex(OBSERVATION_INDEX, observationMapping)) {
|
||||
throw new RuntimeException("Failed to create observation index");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void createCodeIndexIfMissing() throws IOException {
|
||||
if (indexExists(IndexConstants.CODE_INDEX)) {
|
||||
if (indexExists(CODE_INDEX)) {
|
||||
return;
|
||||
}
|
||||
String codeMapping = "{\n" +
|
||||
|
@ -161,7 +168,7 @@ public class ElasticsearchSvcImpl implements IElasticsearchSvc {
|
|||
" }\n" +
|
||||
" }\n" +
|
||||
"}\n";
|
||||
if (!createIndex(IndexConstants.CODE_INDEX, codeMapping)) {
|
||||
if (!createIndex(CODE_INDEX, codeMapping)) {
|
||||
throw new RuntimeException("Failed to create code index");
|
||||
}
|
||||
|
||||
|
@ -199,16 +206,18 @@ public class ElasticsearchSvcImpl implements IElasticsearchSvc {
|
|||
}
|
||||
|
||||
@Override
|
||||
// TODO: Should eliminate dependency on SearchParameterMap in API.
|
||||
public List<String> executeLastN(SearchParameterMap theSearchParameterMap, Integer theMaxObservationsPerCode, Integer theMaxResultsToFetch) {
|
||||
public List<String> executeLastN(SearchParameterMap theSearchParameterMap, FhirContext theFhirContext, Integer theMaxResultsToFetch) {
|
||||
String OBSERVATION_IDENTIFIER_FIELD_NAME = "identifier";
|
||||
String[] topHitsInclude = {OBSERVATION_IDENTIFIER_FIELD_NAME};
|
||||
try {
|
||||
List<SearchResponse> responses = buildAndExecuteSearch(theSearchParameterMap, theMaxObservationsPerCode, topHitsInclude);
|
||||
List<SearchResponse> responses = buildAndExecuteSearch(theSearchParameterMap, theFhirContext, topHitsInclude);
|
||||
List<String> observationIds = new ArrayList<>();
|
||||
for (SearchResponse response : responses) {
|
||||
// observationIds.addAll(buildObservationIdList(response));
|
||||
Integer maxResultsToAdd = theMaxResultsToFetch - observationIds.size();
|
||||
observationIds.addAll(buildObservationList(response, t -> t.getIdentifier(), theSearchParameterMap, maxResultsToAdd));
|
||||
Integer maxResultsToAdd = null;
|
||||
if (theMaxResultsToFetch != null) {
|
||||
maxResultsToAdd = theMaxResultsToFetch - observationIds.size();
|
||||
}
|
||||
observationIds.addAll(buildObservationList(response, ObservationJson::getIdentifier, theSearchParameterMap, theFhirContext, maxResultsToAdd));
|
||||
}
|
||||
return observationIds;
|
||||
} catch (IOException theE) {
|
||||
|
@ -216,23 +225,27 @@ public class ElasticsearchSvcImpl implements IElasticsearchSvc {
|
|||
}
|
||||
}
|
||||
|
||||
private List<SearchResponse> buildAndExecuteSearch(SearchParameterMap theSearchParameterMap, Integer theMaxObservationsPerCode,
|
||||
private List<SearchResponse> buildAndExecuteSearch(SearchParameterMap theSearchParameterMap, FhirContext theFhirContext,
|
||||
String[] topHitsInclude) {
|
||||
List<SearchResponse> responses = new ArrayList<>();
|
||||
if (theSearchParameterMap.containsKey(IndexConstants.PATIENT_SEARCH_PARAM) || theSearchParameterMap.containsKey(IndexConstants.SUBJECT_SEARCH_PARAM)) {
|
||||
String patientParamName = LastNParameterHelper.getPatientParamName(theFhirContext);
|
||||
String subjectParamName = LastNParameterHelper.getSubjectParamName(theFhirContext);
|
||||
if (theSearchParameterMap.containsKey(patientParamName)
|
||||
|| theSearchParameterMap.containsKey(subjectParamName)) {
|
||||
ArrayList<String> subjectReferenceCriteria = new ArrayList<>();
|
||||
List<List<IQueryParameterType>> patientParams = new ArrayList<>();
|
||||
if (theSearchParameterMap.get(IndexConstants.PATIENT_SEARCH_PARAM) != null) {
|
||||
patientParams.addAll(theSearchParameterMap.get(IndexConstants.PATIENT_SEARCH_PARAM));
|
||||
if (theSearchParameterMap.get(patientParamName) != null) {
|
||||
patientParams.addAll(theSearchParameterMap.get(patientParamName));
|
||||
}
|
||||
if (theSearchParameterMap.get(IndexConstants.SUBJECT_SEARCH_PARAM) != null) {
|
||||
patientParams.addAll(theSearchParameterMap.get(IndexConstants.SUBJECT_SEARCH_PARAM));
|
||||
if (theSearchParameterMap.get(subjectParamName) != null) {
|
||||
patientParams.addAll(theSearchParameterMap.get(subjectParamName));
|
||||
}
|
||||
for (List<? extends IQueryParameterType> nextSubjectList : patientParams) {
|
||||
subjectReferenceCriteria.addAll(getReferenceValues(nextSubjectList));
|
||||
}
|
||||
for (String subject : subjectReferenceCriteria) {
|
||||
SearchRequest myLastNRequest = buildObservationsSearchRequest(subject, theSearchParameterMap, createCompositeAggregationBuilder(theMaxObservationsPerCode, topHitsInclude));
|
||||
SearchRequest myLastNRequest = buildObservationsSearchRequest(subject, theSearchParameterMap, theFhirContext,
|
||||
createCompositeAggregationBuilder(theSearchParameterMap.getLastNMax(), topHitsInclude));
|
||||
try {
|
||||
SearchResponse lastnResponse = executeSearchRequest(myLastNRequest);
|
||||
responses.add(lastnResponse);
|
||||
|
@ -241,7 +254,7 @@ public class ElasticsearchSvcImpl implements IElasticsearchSvc {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
SearchRequest myLastNRequest = buildObservationsSearchRequest(theSearchParameterMap, createObservationCodeAggregationBuilder(theMaxObservationsPerCode, topHitsInclude));
|
||||
SearchRequest myLastNRequest = buildObservationsSearchRequest(theSearchParameterMap, theFhirContext, createObservationCodeAggregationBuilder(theSearchParameterMap.getLastNMax(), topHitsInclude));
|
||||
try {
|
||||
SearchResponse lastnResponse = executeSearchRequest(myLastNRequest);
|
||||
responses.add(lastnResponse);
|
||||
|
@ -254,13 +267,12 @@ public class ElasticsearchSvcImpl implements IElasticsearchSvc {
|
|||
}
|
||||
|
||||
@VisibleForTesting
|
||||
// TODO: Should eliminate dependency on SearchParameterMap in API.
|
||||
List<ObservationJson> executeLastNWithAllFields(SearchParameterMap theSearchParameterMap, Integer theMaxObservationsPerCode, Integer theMaxResultsToFetch) {
|
||||
List<ObservationJson> executeLastNWithAllFields(SearchParameterMap theSearchParameterMap, FhirContext theFhirContext) {
|
||||
try {
|
||||
List<SearchResponse> responses = buildAndExecuteSearch(theSearchParameterMap, theMaxObservationsPerCode, null);
|
||||
List<SearchResponse> responses = buildAndExecuteSearch(theSearchParameterMap, theFhirContext, null);
|
||||
List<ObservationJson> observationDocuments = new ArrayList<>();
|
||||
for (SearchResponse response : responses) {
|
||||
observationDocuments.addAll(buildObservationList(response, t -> t, theSearchParameterMap, theMaxResultsToFetch));
|
||||
observationDocuments.addAll(buildObservationList(response, t -> t, theSearchParameterMap, theFhirContext, 100));
|
||||
}
|
||||
return observationDocuments;
|
||||
} catch (IOException theE) {
|
||||
|
@ -269,20 +281,15 @@ public class ElasticsearchSvcImpl implements IElasticsearchSvc {
|
|||
}
|
||||
|
||||
@VisibleForTesting
|
||||
List<CodeJson> queryAllIndexedObservationCodes(int theMaxResultSetSize) throws IOException {
|
||||
SearchRequest codeSearchRequest = buildObservationCodesSearchRequest(theMaxResultSetSize);
|
||||
SearchResponse codeSearchResponse = executeSearchRequest(codeSearchRequest);
|
||||
return buildCodeResult(codeSearchResponse);
|
||||
}
|
||||
|
||||
private SearchRequest buildObservationCodesSearchRequest(int theMaxResultSetSize) {
|
||||
SearchRequest searchRequest = new SearchRequest(IndexConstants.CODE_INDEX);
|
||||
List<CodeJson> queryAllIndexedObservationCodes() throws IOException {
|
||||
SearchRequest codeSearchRequest = new SearchRequest(CODE_INDEX);
|
||||
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
|
||||
// Query
|
||||
searchSourceBuilder.query(QueryBuilders.matchAllQuery());
|
||||
searchSourceBuilder.size(theMaxResultSetSize);
|
||||
searchRequest.source(searchSourceBuilder);
|
||||
return searchRequest;
|
||||
searchSourceBuilder.size(1000);
|
||||
codeSearchRequest.source(searchSourceBuilder);
|
||||
SearchResponse codeSearchResponse = executeSearchRequest(codeSearchRequest);
|
||||
return buildCodeResult(codeSearchResponse);
|
||||
}
|
||||
|
||||
private CompositeAggregationBuilder createCompositeAggregationBuilder(int theMaxNumberObservationsPerCode, String[] theTopHitsInclude) {
|
||||
|
@ -297,51 +304,27 @@ public class ElasticsearchSvcImpl implements IElasticsearchSvc {
|
|||
}
|
||||
|
||||
private TermsAggregationBuilder createObservationCodeAggregationBuilder(int theMaxNumberObservationsPerCode, String[] theTopHitsInclude) {
|
||||
TermsAggregationBuilder observationCodeAggregationBuilder = new TermsAggregationBuilder(GROUP_BY_CODE, ValueType.STRING).field("codeconceptid");
|
||||
TermsAggregationBuilder observationCodeCodeAggregationBuilder = new TermsAggregationBuilder(GROUP_BY_CODE, ValueType.STRING).field("codeconceptcodingcode");
|
||||
// Top Hits Aggregation
|
||||
observationCodeAggregationBuilder.subAggregation(AggregationBuilders.topHits("most_recent_effective")
|
||||
observationCodeCodeAggregationBuilder.subAggregation(AggregationBuilders.topHits("most_recent_effective")
|
||||
.sort("effectivedtm", SortOrder.DESC)
|
||||
.fetchSource(theTopHitsInclude, null).size(theMaxNumberObservationsPerCode));
|
||||
observationCodeAggregationBuilder.size(10000);
|
||||
return observationCodeAggregationBuilder;
|
||||
observationCodeCodeAggregationBuilder.size(10000);
|
||||
TermsAggregationBuilder observationCodeSystemAggregationBuilder = new TermsAggregationBuilder(GROUP_BY_SYSTEM, ValueType.STRING).field("codeconceptcodingsystem");
|
||||
observationCodeSystemAggregationBuilder.subAggregation(observationCodeCodeAggregationBuilder);
|
||||
return observationCodeSystemAggregationBuilder;
|
||||
}
|
||||
|
||||
public SearchResponse executeSearchRequest(SearchRequest searchRequest) throws IOException {
|
||||
private SearchResponse executeSearchRequest(SearchRequest searchRequest) throws IOException {
|
||||
return myRestHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
|
||||
}
|
||||
|
||||
private List<String> buildObservationIdList(SearchResponse theSearchResponse) throws IOException {
|
||||
List<String> theObservationList = new ArrayList<>();
|
||||
for (ParsedComposite.ParsedBucket subjectBucket : getSubjectBuckets(theSearchResponse)) {
|
||||
for (Terms.Bucket observationCodeBucket : getObservationCodeBuckets(subjectBucket)) {
|
||||
for (SearchHit lastNMatch : getLastNMatches(observationCodeBucket)) {
|
||||
String indexedObservation = lastNMatch.getSourceAsString();
|
||||
ObservationJson observationJson = objectMapper.readValue(indexedObservation, ObservationJson.class);
|
||||
theObservationList.add(observationJson.getIdentifier());
|
||||
}
|
||||
}
|
||||
}
|
||||
return theObservationList;
|
||||
}
|
||||
|
||||
private List<ObservationJson> buildObservationDocumentList(SearchResponse theSearchResponse) throws IOException {
|
||||
List<ObservationJson> theObservationList = new ArrayList<>();
|
||||
for (ParsedComposite.ParsedBucket subjectBucket : getSubjectBuckets(theSearchResponse)) {
|
||||
for (Terms.Bucket observationCodeBucket : getObservationCodeBuckets(subjectBucket)) {
|
||||
for (SearchHit lastNMatch : getLastNMatches(observationCodeBucket)) {
|
||||
String indexedObservation = lastNMatch.getSourceAsString();
|
||||
ObservationJson observationJson = objectMapper.readValue(indexedObservation, ObservationJson.class);
|
||||
theObservationList.add(observationJson);
|
||||
}
|
||||
}
|
||||
}
|
||||
return theObservationList;
|
||||
}
|
||||
|
||||
private <T> List<T> buildObservationList(SearchResponse theSearchResponse, Function<ObservationJson,T> setValue,
|
||||
SearchParameterMap theSearchParameterMap, Integer theMaxResultsToFetch) throws IOException {
|
||||
SearchParameterMap theSearchParameterMap, FhirContext theFhirContext,
|
||||
Integer theMaxResultsToFetch) throws IOException {
|
||||
List<T> theObservationList = new ArrayList<>();
|
||||
if (theSearchParameterMap.containsKey(IndexConstants.PATIENT_SEARCH_PARAM) || theSearchParameterMap.containsKey(IndexConstants.SUBJECT_SEARCH_PARAM)) {
|
||||
if (theSearchParameterMap.containsKey(LastNParameterHelper.getPatientParamName(theFhirContext))
|
||||
|| theSearchParameterMap.containsKey(LastNParameterHelper.getSubjectParamName(theFhirContext))) {
|
||||
for (ParsedComposite.ParsedBucket subjectBucket : getSubjectBuckets(theSearchResponse)) {
|
||||
if (theMaxResultsToFetch != null && theObservationList.size() >= theMaxResultsToFetch) {
|
||||
break;
|
||||
|
@ -387,14 +370,23 @@ public class ElasticsearchSvcImpl implements IElasticsearchSvc {
|
|||
|
||||
private List<? extends Terms.Bucket> getObservationCodeBuckets(SearchResponse theSearchResponse) {
|
||||
Aggregations responseAggregations = theSearchResponse.getAggregations();
|
||||
ParsedTerms aggregatedObservationCodes = responseAggregations.get(GROUP_BY_CODE);
|
||||
return aggregatedObservationCodes.getBuckets();
|
||||
return getObservationCodeBuckets(responseAggregations);
|
||||
}
|
||||
|
||||
private List<? extends Terms.Bucket> getObservationCodeBuckets(ParsedComposite.ParsedBucket theSubjectBucket) {
|
||||
Aggregations observationCodeAggregations = theSubjectBucket.getAggregations();
|
||||
ParsedTerms aggregatedObservationCodes = observationCodeAggregations.get(GROUP_BY_CODE);
|
||||
return aggregatedObservationCodes.getBuckets();
|
||||
Aggregations observationCodeSystemAggregations = theSubjectBucket.getAggregations();
|
||||
return getObservationCodeBuckets(observationCodeSystemAggregations);
|
||||
}
|
||||
|
||||
private List<? extends Terms.Bucket> getObservationCodeBuckets(Aggregations theObservationCodeSystemAggregations) {
|
||||
List<Terms.Bucket> retVal = new ArrayList<>();
|
||||
ParsedTerms aggregatedObservationCodeSystems = theObservationCodeSystemAggregations.get(GROUP_BY_SYSTEM);
|
||||
for(Terms.Bucket observationCodeSystem : aggregatedObservationCodeSystems.getBuckets()) {
|
||||
Aggregations observationCodeCodeAggregations = observationCodeSystem.getAggregations();
|
||||
ParsedTerms aggregatedObservationCodeCodes = observationCodeCodeAggregations.get(GROUP_BY_CODE);
|
||||
retVal.addAll(aggregatedObservationCodeCodes.getBuckets());
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
private SearchHit[] getLastNMatches(Terms.Bucket theObservationCodeBucket) {
|
||||
|
@ -413,17 +405,16 @@ public class ElasticsearchSvcImpl implements IElasticsearchSvc {
|
|||
return codes;
|
||||
}
|
||||
|
||||
private SearchRequest buildObservationsSearchRequest(SearchParameterMap theSearchParameterMap, AggregationBuilder theAggregationBuilder) {
|
||||
SearchRequest searchRequest = new SearchRequest(IndexConstants.OBSERVATION_INDEX);
|
||||
private SearchRequest buildObservationsSearchRequest(SearchParameterMap theSearchParameterMap, FhirContext theFhirContext, AggregationBuilder theAggregationBuilder) {
|
||||
SearchRequest searchRequest = new SearchRequest(OBSERVATION_INDEX);
|
||||
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
|
||||
// Query
|
||||
if (!searchParamsHaveLastNCriteria(theSearchParameterMap)) {
|
||||
if (!searchParamsHaveLastNCriteria(theSearchParameterMap, theFhirContext)) {
|
||||
searchSourceBuilder.query(QueryBuilders.matchAllQuery());
|
||||
} else {
|
||||
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
|
||||
addSubjectsCriteria(boolQueryBuilder, theSearchParameterMap);
|
||||
addCategoriesCriteria(boolQueryBuilder, theSearchParameterMap);
|
||||
addObservationCodeCriteria(boolQueryBuilder, theSearchParameterMap);
|
||||
addCategoriesCriteria(boolQueryBuilder, theSearchParameterMap, theFhirContext);
|
||||
addObservationCodeCriteria(boolQueryBuilder, theSearchParameterMap, theFhirContext);
|
||||
searchSourceBuilder.query(boolQueryBuilder);
|
||||
}
|
||||
searchSourceBuilder.size(0);
|
||||
|
@ -435,14 +426,15 @@ public class ElasticsearchSvcImpl implements IElasticsearchSvc {
|
|||
return searchRequest;
|
||||
}
|
||||
|
||||
private SearchRequest buildObservationsSearchRequest(String theSubjectParam, SearchParameterMap theSearchParameterMap, AggregationBuilder theAggregationBuilder) {
|
||||
SearchRequest searchRequest = new SearchRequest(IndexConstants.OBSERVATION_INDEX);
|
||||
private SearchRequest buildObservationsSearchRequest(String theSubjectParam, SearchParameterMap theSearchParameterMap, FhirContext theFhirContext,
|
||||
AggregationBuilder theAggregationBuilder) {
|
||||
SearchRequest searchRequest = new SearchRequest(OBSERVATION_INDEX);
|
||||
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
|
||||
// Query
|
||||
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
|
||||
boolQueryBuilder.must(QueryBuilders.termQuery("subject", theSubjectParam));
|
||||
addCategoriesCriteria(boolQueryBuilder, theSearchParameterMap);
|
||||
addObservationCodeCriteria(boolQueryBuilder, theSearchParameterMap);
|
||||
addCategoriesCriteria(boolQueryBuilder, theSearchParameterMap, theFhirContext);
|
||||
addObservationCodeCriteria(boolQueryBuilder, theSearchParameterMap, theFhirContext);
|
||||
searchSourceBuilder.query(boolQueryBuilder);
|
||||
searchSourceBuilder.size(0);
|
||||
|
||||
|
@ -453,30 +445,12 @@ public class ElasticsearchSvcImpl implements IElasticsearchSvc {
|
|||
return searchRequest;
|
||||
}
|
||||
|
||||
private Boolean searchParamsHaveLastNCriteria(SearchParameterMap theSearchParameterMap) {
|
||||
private Boolean searchParamsHaveLastNCriteria(SearchParameterMap theSearchParameterMap, FhirContext theFhirContext) {
|
||||
return theSearchParameterMap != null &&
|
||||
(theSearchParameterMap.containsKey(IndexConstants.PATIENT_SEARCH_PARAM) || theSearchParameterMap.containsKey(IndexConstants.SUBJECT_SEARCH_PARAM) ||
|
||||
theSearchParameterMap.containsKey(IndexConstants.CATEGORY_SEARCH_PARAM) || theSearchParameterMap.containsKey(IndexConstants.CODE_SEARCH_PARAM));
|
||||
}
|
||||
|
||||
private void addSubjectsCriteria(BoolQueryBuilder theBoolQueryBuilder, SearchParameterMap theSearchParameterMap) {
|
||||
if (theSearchParameterMap.containsKey(IndexConstants.PATIENT_SEARCH_PARAM) || theSearchParameterMap.containsKey(IndexConstants.SUBJECT_SEARCH_PARAM)) {
|
||||
ArrayList<String> subjectReferenceCriteria = new ArrayList<>();
|
||||
List<List<IQueryParameterType>> andOrParams = new ArrayList<>();
|
||||
if (theSearchParameterMap.get(IndexConstants.PATIENT_SEARCH_PARAM) != null) {
|
||||
andOrParams.addAll(theSearchParameterMap.get(IndexConstants.PATIENT_SEARCH_PARAM));
|
||||
}
|
||||
if (theSearchParameterMap.get(IndexConstants.SUBJECT_SEARCH_PARAM) != null) {
|
||||
andOrParams.addAll(theSearchParameterMap.get(IndexConstants.SUBJECT_SEARCH_PARAM));
|
||||
}
|
||||
for (List<? extends IQueryParameterType> nextAnd : andOrParams) {
|
||||
subjectReferenceCriteria.addAll(getReferenceValues(nextAnd));
|
||||
}
|
||||
if (subjectReferenceCriteria.size() > 0) {
|
||||
theBoolQueryBuilder.must(QueryBuilders.termsQuery("subject", subjectReferenceCriteria));
|
||||
}
|
||||
}
|
||||
|
||||
(theSearchParameterMap.containsKey(LastNParameterHelper.getPatientParamName(theFhirContext))
|
||||
|| theSearchParameterMap.containsKey(LastNParameterHelper.getSubjectParamName(theFhirContext))
|
||||
|| theSearchParameterMap.containsKey(LastNParameterHelper.getCategoryParamName(theFhirContext))
|
||||
|| theSearchParameterMap.containsKey(LastNParameterHelper.getCodeParamName(theFhirContext)));
|
||||
}
|
||||
|
||||
private List<String> getReferenceValues(List<? extends IQueryParameterType> referenceParams) {
|
||||
|
@ -496,13 +470,14 @@ public class ElasticsearchSvcImpl implements IElasticsearchSvc {
|
|||
return referenceList;
|
||||
}
|
||||
|
||||
private void addCategoriesCriteria(BoolQueryBuilder theBoolQueryBuilder, SearchParameterMap theSearchParameterMap) {
|
||||
if (theSearchParameterMap.containsKey(IndexConstants.CATEGORY_SEARCH_PARAM)) {
|
||||
private void addCategoriesCriteria(BoolQueryBuilder theBoolQueryBuilder, SearchParameterMap theSearchParameterMap, FhirContext theFhirContext) {
|
||||
String categoryParamName = LastNParameterHelper.getCategoryParamName(theFhirContext);
|
||||
if (theSearchParameterMap.containsKey(categoryParamName)) {
|
||||
ArrayList<String> codeSystemHashList = new ArrayList<>();
|
||||
ArrayList<String> codeOnlyList = new ArrayList<>();
|
||||
ArrayList<String> systemOnlyList = new ArrayList<>();
|
||||
ArrayList<String> textOnlyList = new ArrayList<>();
|
||||
List<List<IQueryParameterType>> andOrParams = theSearchParameterMap.get(IndexConstants.CATEGORY_SEARCH_PARAM);
|
||||
List<List<IQueryParameterType>> andOrParams = theSearchParameterMap.get(categoryParamName);
|
||||
for (List<? extends IQueryParameterType> nextAnd : andOrParams) {
|
||||
codeSystemHashList.addAll(getCodingCodeSystemValues(nextAnd));
|
||||
codeOnlyList.addAll(getCodingCodeOnlyValues(nextAnd));
|
||||
|
@ -593,13 +568,14 @@ public class ElasticsearchSvcImpl implements IElasticsearchSvc {
|
|||
return textOnlyList;
|
||||
}
|
||||
|
||||
private void addObservationCodeCriteria(BoolQueryBuilder theBoolQueryBuilder, SearchParameterMap theSearchParameterMap) {
|
||||
if (theSearchParameterMap.containsKey(IndexConstants.CODE_SEARCH_PARAM)) {
|
||||
private void addObservationCodeCriteria(BoolQueryBuilder theBoolQueryBuilder, SearchParameterMap theSearchParameterMap, FhirContext theFhirContext) {
|
||||
String codeParamName = LastNParameterHelper.getCodeParamName(theFhirContext);
|
||||
if (theSearchParameterMap.containsKey(codeParamName)) {
|
||||
ArrayList<String> codeSystemHashList = new ArrayList<>();
|
||||
ArrayList<String> codeOnlyList = new ArrayList<>();
|
||||
ArrayList<String> systemOnlyList = new ArrayList<>();
|
||||
ArrayList<String> textOnlyList = new ArrayList<>();
|
||||
List<List<IQueryParameterType>> andOrParams = theSearchParameterMap.get(IndexConstants.CODE_SEARCH_PARAM);
|
||||
List<List<IQueryParameterType>> andOrParams = theSearchParameterMap.get(codeParamName);
|
||||
for (List<? extends IQueryParameterType> nextAnd : andOrParams) {
|
||||
codeSystemHashList.addAll(getCodingCodeSystemValues(nextAnd));
|
||||
codeOnlyList.addAll(getCodingCodeOnlyValues(nextAnd));
|
||||
|
@ -634,12 +610,4 @@ public class ElasticsearchSvcImpl implements IElasticsearchSvc {
|
|||
myRestHighLevelClient.deleteByQuery(deleteByQueryRequest, RequestOptions.DEFAULT);
|
||||
}
|
||||
|
||||
/* public void deleteObservationIndex(String theObservationIdentifier) throws IOException {
|
||||
DeleteByQueryRequest deleteByQueryRequest = new DeleteByQueryRequest(IndexConstants.OBSERVATION_DOCUMENT_TYPE);
|
||||
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
|
||||
boolQueryBuilder.must(QueryBuilders.termsQuery(OBSERVATION_IDENTIFIER_FIELD_NAME, theObservationIdentifier));
|
||||
deleteByQueryRequest.setQuery(boolQueryBuilder);
|
||||
myRestHighLevelClient.deleteByQuery(deleteByQueryRequest, RequestOptions.DEFAULT);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
package ca.uhn.fhir.jpa.search.lastn;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface IElasticsearchSvc {
|
||||
List<String> executeLastN(SearchParameterMap theSearchParameterMap, Integer theMaxObservationsPerCode, Integer theMaxResultsToFetch);
|
||||
List<String> executeLastN(SearchParameterMap theSearchParameterMap, FhirContext theFhirContext, Integer theMaxResultsToFetch);
|
||||
}
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
package ca.uhn.fhir.jpa.search.lastn;
|
||||
|
||||
public class IndexConstants {
|
||||
|
||||
// TODO: These should all be moved into ElasticSearchSvcImpl.
|
||||
public static final String OBSERVATION_INDEX = "observation_index";
|
||||
public static final String CODE_INDEX = "code_index";
|
||||
public static final String OBSERVATION_DOCUMENT_TYPE = "ca.uhn.fhir.jpa.dao.lastn.entity.ObservationIndexedSearchParamLastNEntity";
|
||||
public static final String CODE_DOCUMENT_TYPE = "ca.uhn.fhir.jpa.dao.lastn.entity.ObservationIndexedCodeCodeableConceptEntity";
|
||||
|
||||
public static final String SUBJECT_SEARCH_PARAM = "subject";
|
||||
public static final String PATIENT_SEARCH_PARAM = "patient";
|
||||
public static final String CODE_SEARCH_PARAM = "code";
|
||||
public static final String CATEGORY_SEARCH_PARAM = "category";
|
||||
|
||||
}
|
|
@ -104,12 +104,12 @@ public class TestR4Config extends BaseJavaConfigR4 {
|
|||
retVal.setDriver(new org.h2.Driver());
|
||||
// retVal.setDriver(new org.postgresql.Driver());
|
||||
retVal.setUrl("jdbc:h2:mem:testdb_r4");
|
||||
// retVal.setUrl("jdbc:postgresql://localhost:5432/hapi");
|
||||
// retVal.setUrl("jdbc:postgresql://localhost:5432/cdr");
|
||||
retVal.setMaxWaitMillis(10000);
|
||||
retVal.setUsername("");
|
||||
// retVal.setUsername("hapi");
|
||||
// retVal.setUsername("cdr");
|
||||
retVal.setPassword("");
|
||||
// retVal.setPassword("HapiFHIR");
|
||||
// retVal.setPassword("SmileCDR");
|
||||
retVal.setMaxTotal(ourMaxThreads);
|
||||
|
||||
SLF4JLogLevel level = SLF4JLogLevel.INFO;
|
||||
|
|
|
@ -60,6 +60,9 @@ public class PersistObservationIndexedSearchParamLastNR4IT {
|
|||
@Autowired
|
||||
ObservationLastNIndexPersistSvc testObservationPersist;
|
||||
|
||||
@Autowired
|
||||
protected FhirContext myFhirCtx;
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
|
||||
|
@ -106,8 +109,9 @@ public class PersistObservationIndexedSearchParamLastNR4IT {
|
|||
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.setLastNMax(3);
|
||||
|
||||
List<String> observationIdsOnly = elasticsearchSvc.executeLastN(searchParameterMap, 3, 100);
|
||||
List<String> observationIdsOnly = elasticsearchSvc.executeLastN(searchParameterMap, myFhirCtx, 100);
|
||||
|
||||
assertEquals(1, observationIdsOnly.size());
|
||||
assertEquals(SINGLE_OBSERVATION_PID, observationIdsOnly.get(0));
|
||||
|
@ -180,15 +184,18 @@ public class PersistObservationIndexedSearchParamLastNR4IT {
|
|||
// Check that all observations were indexed.
|
||||
SearchParameterMap searchParameterMap = new SearchParameterMap();
|
||||
searchParameterMap.add(Observation.SP_SUBJECT, multiSubjectParams);
|
||||
//searchParameterMap.
|
||||
List<String> observationIdsOnly = elasticsearchSvc.executeLastN(searchParameterMap, 10, 200);
|
||||
|
||||
searchParameterMap.setLastNMax(10);
|
||||
|
||||
List<String> observationIdsOnly = elasticsearchSvc.executeLastN(searchParameterMap, myFhirCtx, 200);
|
||||
assertEquals(100, observationIdsOnly.size());
|
||||
|
||||
// Filter the results by category code.
|
||||
TokenParam categoryParam = new TokenParam(CATEGORYFIRSTCODINGSYSTEM, FIRSTCATEGORYFIRSTCODINGCODE);
|
||||
searchParameterMap.add(Observation.SP_CATEGORY, new TokenAndListParam().addAnd(new TokenOrListParam().addOr(categoryParam)));
|
||||
|
||||
observationIdsOnly = elasticsearchSvc.executeLastN(searchParameterMap, 10, 100);
|
||||
|
||||
observationIdsOnly = elasticsearchSvc.executeLastN(searchParameterMap, myFhirCtx, 100);
|
||||
|
||||
assertEquals(50, observationIdsOnly.size());
|
||||
|
||||
|
@ -277,7 +284,8 @@ public class PersistObservationIndexedSearchParamLastNR4IT {
|
|||
|
||||
SearchParameterMap searchParameterMap = new SearchParameterMap();
|
||||
searchParameterMap.add(Observation.SP_SUBJECT, multiSubjectParams);
|
||||
List<String> observationIdsOnly = elasticsearchSvc.executeLastN(searchParameterMap, 10, 200);
|
||||
searchParameterMap.setLastNMax(10);
|
||||
List<String> observationIdsOnly = elasticsearchSvc.executeLastN(searchParameterMap, myFhirCtx, 200);
|
||||
assertEquals(100, observationIdsOnly.size());
|
||||
assertTrue(observationIdsOnly.contains("55"));
|
||||
|
||||
|
@ -295,7 +303,7 @@ public class PersistObservationIndexedSearchParamLastNR4IT {
|
|||
observation = myResourceIndexedObservationLastNDao.findForIdentifier("55");
|
||||
assertNull(observation);
|
||||
|
||||
observationIdsOnly = elasticsearchSvc.executeLastN(searchParameterMap, 10, 200);
|
||||
observationIdsOnly = elasticsearchSvc.executeLastN(searchParameterMap, myFhirCtx, 200);
|
||||
assertEquals(99, observationIdsOnly.size());
|
||||
assertTrue(!observationIdsOnly.contains("55"));
|
||||
|
||||
|
@ -316,7 +324,9 @@ public class PersistObservationIndexedSearchParamLastNR4IT {
|
|||
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)));
|
||||
List<String> observationIdsOnly = elasticsearchSvc.executeLastN(searchParameterMap, 10, 200);
|
||||
searchParameterMap.setLastNMax(10);
|
||||
|
||||
List<String> observationIdsOnly = elasticsearchSvc.executeLastN(searchParameterMap, myFhirCtx, 200);
|
||||
assertEquals(1, observationIdsOnly.size());
|
||||
assertTrue(observationIdsOnly.contains(SINGLE_OBSERVATION_PID));
|
||||
|
||||
|
@ -339,7 +349,7 @@ public class PersistObservationIndexedSearchParamLastNR4IT {
|
|||
assertEquals(newEffectiveDtm.getValue(), updatedObservationEntity.getEffectiveDtm());
|
||||
|
||||
// Repeat earlier Elasticsearch query. This time, should return no matches.
|
||||
observationIdsOnly = elasticsearchSvc.executeLastN(searchParameterMap, 10, 200);
|
||||
observationIdsOnly = elasticsearchSvc.executeLastN(searchParameterMap, myFhirCtx, 200);
|
||||
assertEquals(0, observationIdsOnly.size());
|
||||
|
||||
// Try again with the new patient ID.
|
||||
|
@ -348,7 +358,8 @@ public class PersistObservationIndexedSearchParamLastNR4IT {
|
|||
searchParameterMap.add(Observation.SP_SUBJECT, new ReferenceAndListParam().addAnd(new ReferenceOrListParam().addOr(subjectParam)));
|
||||
searchParameterMap.add(Observation.SP_CATEGORY, new TokenAndListParam().addAnd(new TokenOrListParam().addOr(categoryParam)));
|
||||
searchParameterMap.add(Observation.SP_CODE, new TokenAndListParam().addAnd(new TokenOrListParam().addOr(codeParam)));
|
||||
observationIdsOnly = elasticsearchSvc.executeLastN(searchParameterMap, 10, 200);
|
||||
searchParameterMap.setLastNMax(10);
|
||||
observationIdsOnly = elasticsearchSvc.executeLastN(searchParameterMap, myFhirCtx, 200);
|
||||
|
||||
// Should see the observation returned now.
|
||||
assertEquals(1, observationIdsOnly.size());
|
||||
|
@ -398,11 +409,13 @@ public class PersistObservationIndexedSearchParamLastNR4IT {
|
|||
SearchParameterMap searchParameterMap = new SearchParameterMap();
|
||||
|
||||
// execute Observation ID search - Composite Aggregation
|
||||
List<String> observationIdsOnly = elasticsearchSvc.executeLastN(searchParameterMap,1, 200);
|
||||
searchParameterMap.setLastNMax(1);
|
||||
List<String> observationIdsOnly = elasticsearchSvc.executeLastN(searchParameterMap,myFhirCtx, 200);
|
||||
|
||||
assertEquals(20, observationIdsOnly.size());
|
||||
|
||||
observationIdsOnly = elasticsearchSvc.executeLastN(searchParameterMap, 3, 200);
|
||||
searchParameterMap.setLastNMax(3);
|
||||
observationIdsOnly = elasticsearchSvc.executeLastN(searchParameterMap, myFhirCtx, 200);
|
||||
|
||||
assertEquals(38, observationIdsOnly.size());
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package ca.uhn.fhir.jpa.search.lastn;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||
import ca.uhn.fhir.rest.param.*;
|
||||
import ca.uhn.fhir.jpa.search.lastn.config.TestElasticsearchConfig;
|
||||
|
@ -21,7 +22,6 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
|||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
import static ca.uhn.fhir.jpa.search.lastn.IndexConstants.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
|
@ -35,6 +35,8 @@ public class LastNElasticsearchSvcMultipleObservationsIT {
|
|||
|
||||
private final Map<String, Map<String, List<Date>>> createdPatientObservationMap = new HashMap<>();
|
||||
|
||||
private FhirContext myFhirContext = FhirContext.forR4();
|
||||
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeClass() {
|
||||
|
@ -51,8 +53,8 @@ public class LastNElasticsearchSvcMultipleObservationsIT {
|
|||
|
||||
@After
|
||||
public void after() throws IOException {
|
||||
elasticsearchSvc.deleteAllDocuments(OBSERVATION_INDEX);
|
||||
elasticsearchSvc.deleteAllDocuments(CODE_INDEX);
|
||||
elasticsearchSvc.deleteAllDocuments(ElasticsearchSvcImpl.OBSERVATION_INDEX);
|
||||
elasticsearchSvc.deleteAllDocuments(ElasticsearchSvcImpl.CODE_INDEX);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -80,8 +82,9 @@ public class LastNElasticsearchSvcMultipleObservationsIT {
|
|||
searchParameterMap.add(Observation.SP_SUBJECT, buildReferenceAndListParam(subjectParam));
|
||||
subjectParam = new ReferenceParam("Patient", "", "9");
|
||||
searchParameterMap.add(Observation.SP_SUBJECT, buildReferenceAndListParam(subjectParam));
|
||||
searchParameterMap.setLastNMax(3);
|
||||
|
||||
List<ObservationJson> observations = elasticsearchSvc.executeLastNWithAllFields(searchParameterMap, 3, 100);
|
||||
List<ObservationJson> observations = elasticsearchSvc.executeLastNWithAllFields(searchParameterMap, myFhirContext);
|
||||
|
||||
assertEquals(60, observations.size());
|
||||
|
||||
|
@ -152,8 +155,9 @@ public class LastNElasticsearchSvcMultipleObservationsIT {
|
|||
TokenParam codeParam1 = new TokenParam("http://mycodes.org/fhir/observation-code", "test-code-1");
|
||||
TokenParam codeParam2 = new TokenParam("http://mycodes.org/fhir/observation-code", "test-code-2");
|
||||
searchParameterMap.add(Observation.SP_CODE, buildTokenAndListParam(codeParam1, codeParam2));
|
||||
searchParameterMap.setLastNMax(100);
|
||||
|
||||
List<String> observations = elasticsearchSvc.executeLastN(searchParameterMap, 100, 100);
|
||||
List<String> observations = elasticsearchSvc.executeLastN(searchParameterMap, myFhirContext, 100);
|
||||
|
||||
assertEquals(20, observations.size());
|
||||
|
||||
|
@ -164,8 +168,9 @@ public class LastNElasticsearchSvcMultipleObservationsIT {
|
|||
searchParameterMap.add(Observation.SP_PATIENT, buildReferenceAndListParam(patientParam1, patientParam2));
|
||||
searchParameterMap.add(Observation.SP_CATEGORY, buildTokenAndListParam(categoryParam1, categoryParam2));
|
||||
searchParameterMap.add(Observation.SP_CODE, buildTokenAndListParam(codeParam1, codeParam2));
|
||||
searchParameterMap.setLastNMax(100);
|
||||
|
||||
observations = elasticsearchSvc.executeLastN(searchParameterMap, 100, 100);
|
||||
observations = elasticsearchSvc.executeLastN(searchParameterMap, myFhirContext, 100);
|
||||
|
||||
assertEquals(20, observations.size());
|
||||
|
||||
|
@ -197,8 +202,9 @@ public class LastNElasticsearchSvcMultipleObservationsIT {
|
|||
searchParameterMap.add(Observation.SP_CATEGORY, buildTokenAndListParam(categoryParam));
|
||||
TokenParam codeParam = new TokenParam("test-code-1");
|
||||
searchParameterMap.add(Observation.SP_CODE, buildTokenAndListParam(codeParam));
|
||||
searchParameterMap.setLastNMax(100);
|
||||
|
||||
List<String> observations = elasticsearchSvc.executeLastN(searchParameterMap, 100, 100);
|
||||
List<String> observations = elasticsearchSvc.executeLastN(searchParameterMap, myFhirContext, 100);
|
||||
|
||||
assertEquals(5, observations.size());
|
||||
|
||||
|
@ -214,8 +220,9 @@ public class LastNElasticsearchSvcMultipleObservationsIT {
|
|||
searchParameterMap.add(Observation.SP_CATEGORY, buildTokenAndListParam(categoryParam));
|
||||
TokenParam codeParam = new TokenParam("http://mycodes.org/fhir/observation-code", null);
|
||||
searchParameterMap.add(Observation.SP_CODE, buildTokenAndListParam(codeParam));
|
||||
searchParameterMap.setLastNMax(100);
|
||||
|
||||
List<String> observations = elasticsearchSvc.executeLastN(searchParameterMap, 100, 100);
|
||||
List<String> observations = elasticsearchSvc.executeLastN(searchParameterMap, myFhirContext, 100);
|
||||
|
||||
assertEquals(10, observations.size());
|
||||
}
|
||||
|
@ -231,8 +238,9 @@ public class LastNElasticsearchSvcMultipleObservationsIT {
|
|||
TokenParam codeParam = new TokenParam("test-code-1 display");
|
||||
codeParam.setModifier(TokenParamModifier.TEXT);
|
||||
searchParameterMap.add(Observation.SP_CODE, buildTokenAndListParam(codeParam));
|
||||
searchParameterMap.setLastNMax(100);
|
||||
|
||||
List<String> observations = elasticsearchSvc.executeLastN(searchParameterMap, 100, 100);
|
||||
List<String> observations = elasticsearchSvc.executeLastN(searchParameterMap, myFhirContext, 100);
|
||||
|
||||
assertEquals(5, observations.size());
|
||||
|
||||
|
@ -248,7 +256,9 @@ public class LastNElasticsearchSvcMultipleObservationsIT {
|
|||
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));
|
||||
List<String> observations = elasticsearchSvc.executeLastN(searchParameterMap, 100, 100);
|
||||
searchParameterMap.setLastNMax(100);
|
||||
|
||||
List<String> observations = elasticsearchSvc.executeLastN(searchParameterMap, myFhirContext, 100);
|
||||
assertEquals(0, observations.size());
|
||||
|
||||
// Invalid subject
|
||||
|
@ -259,7 +269,9 @@ public class LastNElasticsearchSvcMultipleObservationsIT {
|
|||
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));
|
||||
observations = elasticsearchSvc.executeLastN(searchParameterMap, 100, 100);
|
||||
searchParameterMap.setLastNMax(100);
|
||||
|
||||
observations = elasticsearchSvc.executeLastN(searchParameterMap, myFhirContext, 100);
|
||||
assertEquals(0, observations.size());
|
||||
|
||||
// Invalid observation code
|
||||
|
@ -270,7 +282,9 @@ public class LastNElasticsearchSvcMultipleObservationsIT {
|
|||
searchParameterMap.add(Observation.SP_CATEGORY, buildTokenAndListParam(categoryParam));
|
||||
codeParam = new TokenParam("http://mycodes.org/fhir/observation-code", "test-code-999");
|
||||
searchParameterMap.add(Observation.SP_CODE, buildTokenAndListParam(codeParam));
|
||||
observations = elasticsearchSvc.executeLastN(searchParameterMap, 100, 100);
|
||||
searchParameterMap.setLastNMax(100);
|
||||
|
||||
observations = elasticsearchSvc.executeLastN(searchParameterMap, myFhirContext, 100);
|
||||
assertEquals(0, observations.size());
|
||||
|
||||
// Invalid category code
|
||||
|
@ -281,7 +295,9 @@ public class LastNElasticsearchSvcMultipleObservationsIT {
|
|||
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));
|
||||
observations = elasticsearchSvc.executeLastN(searchParameterMap, 100, 100);
|
||||
searchParameterMap.setLastNMax(100);
|
||||
|
||||
observations = elasticsearchSvc.executeLastN(searchParameterMap, myFhirContext, 100);
|
||||
assertEquals(0, observations.size());
|
||||
|
||||
}
|
||||
|
@ -341,12 +357,12 @@ public class LastNElasticsearchSvcMultipleObservationsIT {
|
|||
observationJson.setCategories(categoryConcepts1);
|
||||
observationJson.setCode(codeableConceptField1);
|
||||
observationJson.setCode_concept_id(codeableConceptId1);
|
||||
assertTrue(elasticsearchSvc.performIndex(CODE_INDEX, codeableConceptId1, codeJson1Document, CODE_DOCUMENT_TYPE));
|
||||
assertTrue(elasticsearchSvc.performIndex(ElasticsearchSvcImpl.CODE_INDEX, codeableConceptId1, codeJson1Document, ElasticsearchSvcImpl.CODE_DOCUMENT_TYPE));
|
||||
} else {
|
||||
observationJson.setCategories(categoryConcepts2);
|
||||
observationJson.setCode(codeableConceptField2);
|
||||
observationJson.setCode_concept_id(codeableConceptId2);
|
||||
assertTrue(elasticsearchSvc.performIndex(CODE_INDEX, codeableConceptId2, codeJson2Document, CODE_DOCUMENT_TYPE));
|
||||
assertTrue(elasticsearchSvc.performIndex(ElasticsearchSvcImpl.CODE_INDEX, codeableConceptId2, codeJson2Document, ElasticsearchSvcImpl.CODE_DOCUMENT_TYPE));
|
||||
}
|
||||
|
||||
Calendar observationDate = new GregorianCalendar();
|
||||
|
@ -355,7 +371,7 @@ public class LastNElasticsearchSvcMultipleObservationsIT {
|
|||
observationJson.setEffectiveDtm(effectiveDtm);
|
||||
|
||||
String observationDocument = ourMapperNonPrettyPrint.writeValueAsString(observationJson);
|
||||
assertTrue(elasticsearchSvc.performIndex(OBSERVATION_INDEX, identifier, observationDocument, OBSERVATION_DOCUMENT_TYPE));
|
||||
assertTrue(elasticsearchSvc.performIndex(ElasticsearchSvcImpl.OBSERVATION_INDEX, identifier, observationDocument, ElasticsearchSvcImpl.OBSERVATION_DOCUMENT_TYPE));
|
||||
|
||||
if (createdPatientObservationMap.containsKey(subject)) {
|
||||
Map<String, List<Date>> observationCodeMap = createdPatientObservationMap.get(subject);
|
||||
|
@ -393,7 +409,8 @@ public class LastNElasticsearchSvcMultipleObservationsIT {
|
|||
@Test
|
||||
public void testLastNNoParamsQuery() {
|
||||
SearchParameterMap searchParameterMap = new SearchParameterMap();
|
||||
List<ObservationJson> observations = elasticsearchSvc.executeLastNWithAllFields(searchParameterMap, 1, 100);
|
||||
searchParameterMap.setLastNMax(1);
|
||||
List<ObservationJson> observations = elasticsearchSvc.executeLastNWithAllFields(searchParameterMap, myFhirContext);
|
||||
|
||||
assertEquals(2, observations.size());
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package ca.uhn.fhir.jpa.search.lastn;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jpa.search.lastn.config.TestElasticsearchConfig;
|
||||
import ca.uhn.fhir.jpa.search.lastn.json.CodeJson;
|
||||
import ca.uhn.fhir.jpa.search.lastn.json.ObservationJson;
|
||||
|
@ -67,12 +68,14 @@ public class LastNElasticsearchSvcSingleObservationIT {
|
|||
final String CODEFIRSTCODINGSYSTEM = "http://mycodes.org/fhir/observation-code";
|
||||
final String CODEFIRSTCODINGCODE = "test-code";
|
||||
final String CODEFIRSTCODINGDISPLAY = "test-code display";
|
||||
final String CODESECONDCODINGSYSTEM = "http://myalternatecodes.org/fhir/observation-code";
|
||||
final String CODESECONDCODINGCODE = "test-alt-code";
|
||||
final String CODESECONDCODINGDISPLAY = "test-alt-code display";
|
||||
final String CODETHIRDCODINGSYSTEM = "http://mysecondaltcodes.org/fhir/observation-code";
|
||||
final String CODETHIRDCODINGCODE = "test-second-alt-code";
|
||||
final String CODETHIRDCODINGDISPLAY = "test-second-alt-code display";
|
||||
// final String CODESECONDCODINGSYSTEM = "http://myalternatecodes.org/fhir/observation-code";
|
||||
// final String CODESECONDCODINGCODE = "test-alt-code";
|
||||
// final String CODESECONDCODINGDISPLAY = "test-alt-code display";
|
||||
// final String CODETHIRDCODINGSYSTEM = "http://mysecondaltcodes.org/fhir/observation-code";
|
||||
// final String CODETHIRDCODINGCODE = "test-second-alt-code";
|
||||
// final String CODETHIRDCODINGDISPLAY = "test-second-alt-code display";
|
||||
|
||||
final FhirContext myFhirContext = FhirContext.forR4();
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeClass() {
|
||||
|
@ -85,8 +88,8 @@ public class LastNElasticsearchSvcSingleObservationIT {
|
|||
|
||||
@After
|
||||
public void after() throws IOException {
|
||||
elasticsearchSvc.deleteAllDocuments(IndexConstants.OBSERVATION_INDEX);
|
||||
elasticsearchSvc.deleteAllDocuments(IndexConstants.CODE_INDEX);
|
||||
elasticsearchSvc.deleteAllDocuments(ElasticsearchSvcImpl.OBSERVATION_INDEX);
|
||||
elasticsearchSvc.deleteAllDocuments(ElasticsearchSvcImpl.CODE_INDEX);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -102,14 +105,16 @@ public class LastNElasticsearchSvcSingleObservationIT {
|
|||
TokenParam codeParam = new TokenParam(CODEFIRSTCODINGSYSTEM, CODEFIRSTCODINGCODE);
|
||||
searchParameterMap.add(Observation.SP_CODE, new TokenAndListParam().addAnd(new TokenOrListParam().addOr(codeParam)));
|
||||
|
||||
searchParameterMap.setLastNMax(3);
|
||||
|
||||
// execute Observation ID search
|
||||
List<String> observationIdsOnly = elasticsearchSvc.executeLastN(searchParameterMap, 3, 100);
|
||||
List<String> observationIdsOnly = elasticsearchSvc.executeLastN(searchParameterMap, myFhirContext, 100);
|
||||
|
||||
assertEquals(1, observationIdsOnly.size());
|
||||
assertEquals(RESOURCEPID, observationIdsOnly.get(0));
|
||||
|
||||
// execute Observation search for all search fields
|
||||
List<ObservationJson> observations = elasticsearchSvc.executeLastNWithAllFields(searchParameterMap, 3, 100);
|
||||
List<ObservationJson> observations = elasticsearchSvc.executeLastNWithAllFields(searchParameterMap, myFhirContext);
|
||||
|
||||
validateFullObservationSearch(observations);
|
||||
}
|
||||
|
@ -243,7 +248,7 @@ public class LastNElasticsearchSvcSingleObservationIT {
|
|||
assertEquals(String.valueOf(CodeSystemHash.hashCodeSystem(CODEFIRSTCODINGSYSTEM, CODEFIRSTCODINGCODE)), code_coding_code_system_hash);
|
||||
|
||||
// Retrieve all Observation codes
|
||||
List<CodeJson> codes = elasticsearchSvc.queryAllIndexedObservationCodes(1000);
|
||||
List<CodeJson> codes = elasticsearchSvc.queryAllIndexedObservationCodes();
|
||||
assertEquals(1, codes.size());
|
||||
CodeJson persistedObservationCode = codes.get(0);
|
||||
|
||||
|
@ -331,11 +336,11 @@ public class LastNElasticsearchSvcSingleObservationIT {
|
|||
indexedObservation.setCode(codeableConceptField);
|
||||
|
||||
String observationDocument = ourMapperNonPrettyPrint.writeValueAsString(indexedObservation);
|
||||
assertTrue(elasticsearchSvc.performIndex(IndexConstants.OBSERVATION_INDEX, RESOURCEPID, observationDocument, IndexConstants.OBSERVATION_DOCUMENT_TYPE));
|
||||
assertTrue(elasticsearchSvc.performIndex(ElasticsearchSvcImpl.OBSERVATION_INDEX, RESOURCEPID, observationDocument, ElasticsearchSvcImpl.OBSERVATION_DOCUMENT_TYPE));
|
||||
|
||||
CodeJson observationCode = new CodeJson(codeableConceptField, OBSERVATIONSINGLECODEID);
|
||||
String codeDocument = ourMapperNonPrettyPrint.writeValueAsString(observationCode);
|
||||
assertTrue(elasticsearchSvc.performIndex(IndexConstants.CODE_INDEX, OBSERVATIONSINGLECODEID, codeDocument, IndexConstants.CODE_DOCUMENT_TYPE));
|
||||
assertTrue(elasticsearchSvc.performIndex(ElasticsearchSvcImpl.CODE_INDEX, OBSERVATIONSINGLECODEID, codeDocument, ElasticsearchSvcImpl.CODE_DOCUMENT_TYPE));
|
||||
|
||||
try {
|
||||
Thread.sleep(1000L);
|
||||
|
|
|
@ -35,4 +35,66 @@ public class LastNParameterHelper {
|
|||
throw new InvalidRequestException("$lastn operation is not implemented for FHIR Version " + theContext.getVersion().getVersion().getFhirVersionString());
|
||||
}
|
||||
}
|
||||
|
||||
public static String getSubjectParamName(FhirContext theContext) {
|
||||
if (theContext.getVersion().getVersion() == FhirVersionEnum.R5) {
|
||||
return org.hl7.fhir.r5.model.Observation.SP_SUBJECT;
|
||||
} else if (theContext.getVersion().getVersion() == FhirVersionEnum.R4) {
|
||||
return org.hl7.fhir.r4.model.Observation.SP_SUBJECT;
|
||||
} else if (theContext.getVersion().getVersion() == FhirVersionEnum.DSTU3) {
|
||||
return org.hl7.fhir.dstu3.model.Observation.SP_SUBJECT;
|
||||
} else {
|
||||
throw new InvalidRequestException("$lastn operation is not implemented for FHIR Version " + theContext.getVersion().getVersion().getFhirVersionString());
|
||||
}
|
||||
}
|
||||
|
||||
public static String getPatientParamName(FhirContext theContext) {
|
||||
if (theContext.getVersion().getVersion() == FhirVersionEnum.R5) {
|
||||
return org.hl7.fhir.r5.model.Observation.SP_PATIENT;
|
||||
} else if (theContext.getVersion().getVersion() == FhirVersionEnum.R4) {
|
||||
return org.hl7.fhir.r4.model.Observation.SP_PATIENT;
|
||||
} else if (theContext.getVersion().getVersion() == FhirVersionEnum.DSTU3) {
|
||||
return org.hl7.fhir.dstu3.model.Observation.SP_PATIENT;
|
||||
} else {
|
||||
throw new InvalidRequestException("$lastn operation is not implemented for FHIR Version " + theContext.getVersion().getVersion().getFhirVersionString());
|
||||
}
|
||||
}
|
||||
|
||||
public static String getEffectiveParamName(FhirContext theContext) {
|
||||
if (theContext.getVersion().getVersion() == FhirVersionEnum.R5) {
|
||||
return org.hl7.fhir.r5.model.Observation.SP_DATE;
|
||||
} else if (theContext.getVersion().getVersion() == FhirVersionEnum.R4) {
|
||||
return org.hl7.fhir.r4.model.Observation.SP_DATE;
|
||||
} else if (theContext.getVersion().getVersion() == FhirVersionEnum.DSTU3) {
|
||||
return org.hl7.fhir.dstu3.model.Observation.SP_DATE;
|
||||
} else {
|
||||
throw new InvalidRequestException("$lastn operation is not implemented for FHIR Version " + theContext.getVersion().getVersion().getFhirVersionString());
|
||||
}
|
||||
}
|
||||
|
||||
public static String getCategoryParamName(FhirContext theContext) {
|
||||
if (theContext.getVersion().getVersion() == FhirVersionEnum.R5) {
|
||||
return org.hl7.fhir.r5.model.Observation.SP_CATEGORY;
|
||||
} else if (theContext.getVersion().getVersion() == FhirVersionEnum.R4) {
|
||||
return org.hl7.fhir.r4.model.Observation.SP_CATEGORY;
|
||||
} else if (theContext.getVersion().getVersion() == FhirVersionEnum.DSTU3) {
|
||||
return org.hl7.fhir.dstu3.model.Observation.SP_CATEGORY;
|
||||
} else {
|
||||
throw new InvalidRequestException("$lastn operation is not implemented for FHIR Version " + theContext.getVersion().getVersion().getFhirVersionString());
|
||||
}
|
||||
}
|
||||
|
||||
public static String getCodeParamName(FhirContext theContext) {
|
||||
if (theContext.getVersion().getVersion() == FhirVersionEnum.R5) {
|
||||
return org.hl7.fhir.r5.model.Observation.SP_CODE;
|
||||
} else if (theContext.getVersion().getVersion() == FhirVersionEnum.R4) {
|
||||
return org.hl7.fhir.r4.model.Observation.SP_CODE;
|
||||
} else if (theContext.getVersion().getVersion() == FhirVersionEnum.DSTU3) {
|
||||
return org.hl7.fhir.dstu3.model.Observation.SP_CODE;
|
||||
} else {
|
||||
throw new InvalidRequestException("$lastn operation is not implemented for FHIR Version " + theContext.getVersion().getVersion().getFhirVersionString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue