Fixed problems with results of chunked queries being incorrectly sorted.
This commit is contained in:
parent
b250ac4f3d
commit
5cc77b78d4
|
@ -20,14 +20,27 @@ package ca.uhn.fhir.jpa.dao;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import ca.uhn.fhir.interceptor.model.RequestPartitionId;
|
||||
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoObservation;
|
||||
import ca.uhn.fhir.jpa.partition.IRequestPartitionHelperSvc;
|
||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterType;
|
||||
import ca.uhn.fhir.rest.api.*;
|
||||
import ca.uhn.fhir.rest.api.server.*;
|
||||
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
|
||||
import ca.uhn.fhir.rest.param.ReferenceParam;
|
||||
import org.hl7.fhir.instance.model.api.*;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.TreeMap;
|
||||
|
||||
public abstract class BaseHapiFhirResourceDaoObservation<T extends IBaseResource> extends BaseHapiFhirResourceDao<T> implements IFhirResourceDaoObservation<T> {
|
||||
|
||||
@Autowired
|
||||
private IRequestPartitionHelperSvc myRequestPartitionHelperService;
|
||||
|
||||
protected void updateSearchParamsForLastn(SearchParameterMap theSearchParameterMap, RequestDetails theRequestDetails) {
|
||||
if (!isPagingProviderDatabaseBacked(theRequestDetails)) {
|
||||
theSearchParameterMap.setLoadSynchronous(true);
|
||||
|
@ -37,12 +50,51 @@ public abstract class BaseHapiFhirResourceDaoObservation<T extends IBaseResource
|
|||
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())) {
|
||||
fixSubjectParamsOrderForLastn(theSearchParameterMap, theRequestDetails);
|
||||
theSearchParameterMap.setSort(new SortSpec(getSubjectParamName()).setOrder(SortOrderEnum.ASC).setChain(observationCode));
|
||||
} else {
|
||||
theSearchParameterMap.setSort(observationCode);
|
||||
}
|
||||
}
|
||||
|
||||
private void fixSubjectParamsOrderForLastn(SearchParameterMap theSearchParameterMap, RequestDetails theRequestDetails) {
|
||||
// Need to ensure that the patient/subject parameters are sorted in the SearchParameterMap to ensure correct ordering of
|
||||
// the output. The reason for this is that observations are indexed by patient/subject forced ID, but then ordered in the
|
||||
// final result set by subject/patient resource PID.
|
||||
TreeMap<Long, IQueryParameterType> orderedSubjectReferenceMap = new TreeMap<>();
|
||||
if(theSearchParameterMap.containsKey(getSubjectParamName())) {
|
||||
|
||||
RequestPartitionId requestPartitionId = myRequestPartitionHelperService.determineReadPartitionForRequest(theRequestDetails, getResourceName());
|
||||
|
||||
List<List<IQueryParameterType>> patientParams = new ArrayList<>();
|
||||
if (theSearchParameterMap.get(getPatientParamName()) != null) {
|
||||
patientParams.addAll(theSearchParameterMap.get(getPatientParamName()));
|
||||
}
|
||||
if (theSearchParameterMap.get(getSubjectParamName()) != null) {
|
||||
patientParams.addAll(theSearchParameterMap.get(getSubjectParamName()));
|
||||
}
|
||||
|
||||
for (List<? extends IQueryParameterType> nextPatientList : patientParams) {
|
||||
for (IQueryParameterType nextOr : nextPatientList) {
|
||||
if (nextOr instanceof ReferenceParam) {
|
||||
ReferenceParam ref = (ReferenceParam) nextOr;
|
||||
ResourcePersistentId pid = myIdHelperService.resolveResourcePersistentIds(requestPartitionId, ref.getResourceType(), ref.getIdPart());
|
||||
orderedSubjectReferenceMap.put(pid.getIdAsLong(), nextOr);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Invalid token type (expecting ReferenceParam): " + nextOr.getClass());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
theSearchParameterMap.remove(getSubjectParamName());
|
||||
theSearchParameterMap.remove(getPatientParamName());
|
||||
for (Long subjectPid : orderedSubjectReferenceMap.keySet()) {
|
||||
theSearchParameterMap.add(getSubjectParamName(), orderedSubjectReferenceMap.get(subjectPid));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
abstract protected String getEffectiveParamName();
|
||||
abstract protected String getCodeParamName();
|
||||
abstract protected String getSubjectParamName();
|
||||
|
|
|
@ -32,6 +32,7 @@ import org.shadehapi.elasticsearch.search.SearchHits;
|
|||
import org.shadehapi.elasticsearch.search.aggregations.AggregationBuilder;
|
||||
import org.shadehapi.elasticsearch.search.aggregations.AggregationBuilders;
|
||||
import org.shadehapi.elasticsearch.search.aggregations.Aggregations;
|
||||
import org.shadehapi.elasticsearch.search.aggregations.BucketOrder;
|
||||
import org.shadehapi.elasticsearch.search.aggregations.bucket.composite.*;
|
||||
import org.shadehapi.elasticsearch.search.aggregations.bucket.terms.ParsedTerms;
|
||||
import org.shadehapi.elasticsearch.search.aggregations.bucket.terms.Terms;
|
||||
|
@ -44,7 +45,6 @@ import org.shadehapi.elasticsearch.search.sort.SortOrder;
|
|||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.TreeSet;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||
|
@ -149,9 +149,6 @@ public class ElasticsearchSvcImpl implements IElasticsearchSvc {
|
|||
" \"type\" : \"keyword\",\n" +
|
||||
" \"store\" : true\n" +
|
||||
" },\n" +
|
||||
" \"codeable_concept_text\" : {\n" +
|
||||
" \"type\" : \"text\"\n" +
|
||||
" },\n" +
|
||||
" \"codingcode\" : {\n" +
|
||||
" \"type\" : \"keyword\"\n" +
|
||||
" },\n" +
|
||||
|
@ -163,6 +160,9 @@ public class ElasticsearchSvcImpl implements IElasticsearchSvc {
|
|||
" },\n" +
|
||||
" \"codingsystem\" : {\n" +
|
||||
" \"type\" : \"keyword\"\n" +
|
||||
" },\n" +
|
||||
" \"text\" : {\n" +
|
||||
" \"type\" : \"text\"\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
|
@ -247,8 +247,8 @@ public class ElasticsearchSvcImpl implements IElasticsearchSvc {
|
|||
return subjectReferenceCriteria;
|
||||
}
|
||||
|
||||
private TreeSet<String> getReferenceValues(List<? extends IQueryParameterType> referenceParams) {
|
||||
TreeSet<String> referenceList = new TreeSet<>();
|
||||
private List<String> getReferenceValues(List<? extends IQueryParameterType> referenceParams) {
|
||||
List<String> referenceList = new ArrayList<>();
|
||||
|
||||
for (IQueryParameterType nextOr : referenceParams) {
|
||||
|
||||
|
@ -277,12 +277,14 @@ public class ElasticsearchSvcImpl implements IElasticsearchSvc {
|
|||
|
||||
private TermsAggregationBuilder createObservationCodeAggregationBuilder(int theMaxNumberObservationsPerCode, String[] theTopHitsInclude) {
|
||||
TermsAggregationBuilder observationCodeCodeAggregationBuilder = new TermsAggregationBuilder(GROUP_BY_CODE, ValueType.STRING).field("codeconceptcodingcode");
|
||||
observationCodeCodeAggregationBuilder.order(BucketOrder.key(true));
|
||||
// Top Hits Aggregation
|
||||
observationCodeCodeAggregationBuilder.subAggregation(AggregationBuilders.topHits("most_recent_effective")
|
||||
.sort("effectivedtm", SortOrder.DESC)
|
||||
.fetchSource(theTopHitsInclude, null).size(theMaxNumberObservationsPerCode));
|
||||
observationCodeCodeAggregationBuilder.size(10000);
|
||||
TermsAggregationBuilder observationCodeSystemAggregationBuilder = new TermsAggregationBuilder(GROUP_BY_SYSTEM, ValueType.STRING).field("codeconceptcodingsystem");
|
||||
observationCodeSystemAggregationBuilder.order(BucketOrder.key(true));
|
||||
observationCodeSystemAggregationBuilder.subAggregation(observationCodeCodeAggregationBuilder);
|
||||
return observationCodeSystemAggregationBuilder;
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ public class CodeJson {
|
|||
@JsonProperty(value = "codeable_concept_id", required = false)
|
||||
private String myCodeableConceptId;
|
||||
|
||||
@JsonProperty(value = "codeable_concept_text", required = false)
|
||||
@JsonProperty(value = "text", required = false)
|
||||
private String myCodeableConceptText;
|
||||
|
||||
@JsonProperty(value = "codingcode", required = false)
|
||||
|
|
|
@ -15,7 +15,7 @@ import java.util.concurrent.TimeUnit;
|
|||
@Configuration
|
||||
public class TestElasticsearchConfig {
|
||||
|
||||
private final String elasticsearchHost = "127.0.0.1";
|
||||
private final String elasticsearchHost = "localhost";
|
||||
private final String elasticsearchUserId = "";
|
||||
private final String elasticsearchPassword = "";
|
||||
|
||||
|
|
Loading…
Reference in New Issue