Skip to content

Commit

Permalink
Use SELECT COUNT to get number of patients
Browse files Browse the repository at this point in the history
instead of returning all IDs and using size().
  • Loading branch information
askask committed Nov 8, 2024
1 parent a9406f2 commit 2d4d876
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 7 deletions.
10 changes: 5 additions & 5 deletions src/main/java/org/highmed/numportal/service/AqlService.java
Original file line number Diff line number Diff line change
Expand Up @@ -250,19 +250,19 @@ public long getAqlSize(SlimAqlDto aql, String userId) {

validateQuery(aql.getQuery());

Set<String> ehrIds;
int numberOfPatients;
try {
ehrIds =
ehrBaseService.retrieveEligiblePatientIds(Aql.builder().query(aql.getQuery()).build());
numberOfPatients =
ehrBaseService.retrieveNumberOfPatients(Aql.builder().query(aql.getQuery()).build());
} catch (AqlParseException e) {
throw new BadRequestException(AqlParseException.class, e.getLocalizedMessage(), e.getMessage());
}

if (ehrIds.size() < privacyProperties.getMinHits()) {
if (numberOfPatients < privacyProperties.getMinHits()) {
log.warn(TOO_FEW_MATCHES_RESULTS_WITHHELD_FOR_PRIVACY_REASONS);
throw new PrivacyException(AqlService.class, TOO_FEW_MATCHES_RESULTS_WITHHELD_FOR_PRIVACY_REASONS);
}
return ehrIds.size();
return numberOfPatients;
}

public List<AqlCategory> getAqlCategories() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import org.apache.commons.lang3.StringUtils;
import org.ehrbase.openehr.sdk.aql.dto.AqlQuery;
import org.ehrbase.openehr.sdk.aql.dto.containment.ContainmentClassExpression;
import org.ehrbase.openehr.sdk.aql.dto.operand.CountDistinctAggregateFunction;
import org.ehrbase.openehr.sdk.aql.dto.operand.IdentifiedPath;
import org.ehrbase.openehr.sdk.aql.dto.path.AqlObjectPath;
import org.ehrbase.openehr.sdk.aql.dto.select.SelectExpression;
Expand Down Expand Up @@ -118,6 +119,51 @@ public Set<String> retrieveEligiblePatientIds(String query) {
}
}

/**
* Retrieves the number of patients for the given aql
*
* @param aql The aql to retrieve patient ids for
* @return number of patients
* @throws WrongStatusCodeException in case if a malformed aql
*/
public int retrieveNumberOfPatients(Aql aql) {
return retrieveNumberOfPatients(aql.getQuery());
}

public int retrieveNumberOfPatients(String query) {
log.debug("EhrBase retrieve number of patients for query: {} ", query);
AqlQuery dto = AqlQueryParser.parse(query);
SelectExpression selectExpression = new SelectExpression();

var count = new CountDistinctAggregateFunction();
selectExpression.setColumnExpression(count);

IdentifiedPath ehrIdPath = new IdentifiedPath();
ehrIdPath.setPath(AqlObjectPath.parse(AqlQueryConstants.EHR_ID_PATH));

ContainmentClassExpression containmentClassExpression = new ContainmentClassExpression();
containmentClassExpression.setType(AqlQueryConstants.EHR_TYPE);
containmentClassExpression.setIdentifier(AqlQueryConstants.EHR_CONTAINMENT_IDENTIFIER);
ehrIdPath.setRoot(containmentClassExpression);

count.setIdentifiedPath(ehrIdPath);

dto.getSelect().setStatement(List.of(selectExpression));
log.info("Generated query for retrieveNumberOfPatients {} ", AqlRenderer.render(dto));

try {
List<Record1<Integer>> results = restClient.aqlEndpoint().execute(Query.buildNativeQuery(AqlRenderer.render(dto), Integer.class));
return results.get(0).value1();
} catch (WrongStatusCodeException e) {
log.error(INVALID_AQL_QUERY, e.getMessage(), e);
throw new WrongStatusCodeException("EhrBaseService.class", 93, 1);
} catch (ClientException e) {
log.error(ERROR_MESSAGE, e.getMessage(), e);
throw new SystemException(EhrBaseService.class, AN_ERROR_HAS_OCCURRED_CANNOT_EXECUTE_AQL,
String.format(AN_ERROR_HAS_OCCURRED_CANNOT_EXECUTE_AQL, e.getMessage()));
}
}

/**
* Executes a raw aql query
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ public void getAqlSizeTest() {
SlimAqlDto aqlDto = SlimAqlDto.builder()
.query("select * from dummy_table")
.build();
Mockito.when(ehrBaseService.retrieveEligiblePatientIds(Mockito.any(Aql.class))).thenReturn(new HashSet<>(Arrays.asList("id1", "id2", "id3", "id4")));
Mockito.when(ehrBaseService.retrieveNumberOfPatients(Mockito.any(Aql.class))).thenReturn(4);
aqlService.getAqlSize(aqlDto, "4");
}

Expand All @@ -180,7 +180,7 @@ public void shouldHandlePrivacyExceptionWhenGetAqlSize() {
SlimAqlDto aqlDto = SlimAqlDto.builder()
.query("select * from dummy_table")
.build();
Mockito.when(ehrBaseService.retrieveEligiblePatientIds(Mockito.any(Aql.class))).thenReturn(new HashSet<>(Arrays.asList("id1")));
Mockito.when(ehrBaseService.retrieveNumberOfPatients(Mockito.any(Aql.class))).thenReturn(1);
aqlService.getAqlSize(aqlDto, "4");
}

Expand Down

0 comments on commit 2d4d876

Please sign in to comment.