Fixed implementation based on the feedback.
This commit is contained in:
parent
170cf245cc
commit
954fbf054f
|
@ -1,23 +1,28 @@
|
|||
package ca.uhn.fhir.jpa.empi.provider;
|
||||
|
||||
import ca.uhn.fhir.parser.IParser;
|
||||
import ca.uhn.fhir.empi.api.EmpiConstants;
|
||||
import com.google.common.collect.Ordering;
|
||||
import org.hl7.fhir.r4.model.Bundle;
|
||||
import org.hl7.fhir.r4.model.Enumerations;
|
||||
import org.hl7.fhir.r4.model.Extension;
|
||||
import org.hl7.fhir.r4.model.Patient;
|
||||
import org.hl7.fhir.r4.model.codesystems.MatchGrade;
|
||||
import org.junit.Assert;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class EmpiProviderMatchR4Test extends BaseProviderR4Test {
|
||||
|
||||
private static final Logger ourLog = LoggerFactory.getLogger(EmpiProviderMatchR4Test.class);
|
||||
|
||||
public static final String NAME_GIVEN_JANET = NAME_GIVEN_JANE + "t";
|
||||
|
||||
@Override
|
||||
@BeforeEach
|
||||
public void before() {
|
||||
|
@ -41,12 +46,38 @@ public class EmpiProviderMatchR4Test extends BaseProviderR4Test {
|
|||
Bundle.BundleEntrySearchComponent searchComponent = entry0.getSearch();
|
||||
assertEquals(Bundle.SearchEntryMode.MATCH, searchComponent.getMode());
|
||||
|
||||
assertEquals(2.0/3.0, searchComponent.getScore().doubleValue(), 0.01);
|
||||
Extension matchGradeExtension = searchComponent.getExtensionByUrl("http://hl7.org/fhir/StructureDefinition/match-grade");
|
||||
assertEquals(2.0 / 3.0, searchComponent.getScore().doubleValue(), 0.01);
|
||||
Extension matchGradeExtension = searchComponent.getExtensionByUrl(EmpiConstants.FIHR_STRUCTURE_DEF_MATCH_GRADE_URL_NAMESPACE);
|
||||
assertNotNull(matchGradeExtension);
|
||||
assertEquals(MatchGrade.CERTAIN.toCode(), matchGradeExtension.getValue().toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMatchOrder() throws Exception {
|
||||
Patient jane0 = buildJanePatient();
|
||||
Patient createdJane1 = createPatient(jane0);
|
||||
|
||||
Patient jane1 = buildPatientWithNameAndId(NAME_GIVEN_JANET, JANE_ID);
|
||||
jane1.setActive(true);
|
||||
Patient createdJane2 = createPatient(jane1);
|
||||
|
||||
Patient newJane = buildJanePatient();
|
||||
|
||||
Bundle result = myEmpiProviderR4.match(newJane);
|
||||
assertEquals(2, result.getEntry().size());
|
||||
|
||||
Bundle.BundleEntryComponent entry0 = result.getEntry().get(0);
|
||||
assertTrue(jane0.getId().equals(((Patient) entry0.getResource()).getId()), "First match should be Jane");
|
||||
Bundle.BundleEntryComponent entry1 = result.getEntry().get(1);
|
||||
assertTrue(jane1.getId().equals(((Patient) entry1.getResource()).getId()), "Second match should be Janet");
|
||||
|
||||
List<Double> scores = result.getEntry()
|
||||
.stream()
|
||||
.map(bec -> bec.getSearch().getScore().doubleValue())
|
||||
.collect(Collectors.toList());
|
||||
assertTrue(Ordering.<Double>natural().reverse().isOrdered(scores), "Match scores must be descending");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMismatch() throws Exception {
|
||||
Patient jane = buildJanePatient();
|
||||
|
|
|
@ -32,5 +32,6 @@ public class EmpiConstants {
|
|||
public static final String HAPI_ENTERPRISE_IDENTIFIER_SYSTEM = "http://hapifhir.io/fhir/NamingSystem/empi-person-enterprise-id";
|
||||
public static final String ALL_RESOURCE_SEARCH_PARAM_TYPE = "*";
|
||||
|
||||
public static final String FIHR_STRUCTURE_DEF_MATCH_GRADE_URL_NAMESPACE = "http://hl7.org/fhir/StructureDefinition/match-grade";
|
||||
|
||||
}
|
||||
|
|
|
@ -117,7 +117,12 @@ public final class EmpiMatchOutcome {
|
|||
} else if (score > vector) {
|
||||
return 1.0;
|
||||
}
|
||||
return score / vector;
|
||||
|
||||
double retVal = score / vector;
|
||||
if (retVal < 0) {
|
||||
retVal = 0.0;
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -21,6 +21,7 @@ package ca.uhn.fhir.empi.provider;
|
|||
*/
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.empi.api.EmpiConstants;
|
||||
import ca.uhn.fhir.empi.api.EmpiLinkJson;
|
||||
import ca.uhn.fhir.empi.api.IEmpiControllerSvc;
|
||||
import ca.uhn.fhir.empi.api.IEmpiExpungeSvc;
|
||||
|
@ -52,6 +53,7 @@ import org.hl7.fhir.instance.model.api.IAnyResource;
|
|||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Stream;
|
||||
|
@ -77,11 +79,13 @@ public class EmpiProviderDstu3 extends BaseEmpiProvider {
|
|||
}
|
||||
|
||||
@Operation(name = ProviderConstants.EMPI_MATCH, type = Patient.class)
|
||||
public Bundle match(@OperationParam(name=ProviderConstants.EMPI_MATCH_RESOURCE, min = 1, max = 1) Patient thePatient) {
|
||||
public Bundle match(@OperationParam(name = ProviderConstants.EMPI_MATCH_RESOURCE, min = 1, max = 1) Patient thePatient) {
|
||||
if (thePatient == null) {
|
||||
throw new InvalidRequestException("resource may not be null");
|
||||
}
|
||||
|
||||
List<MatchedTarget> matches = myEmpiMatchFinderSvc.getMatchedTargets("Patient", thePatient);
|
||||
matches.sort(Comparator.comparing((MatchedTarget m) -> m.getMatchResult().getNormalizedScore()).reversed());
|
||||
|
||||
Bundle retVal = new Bundle();
|
||||
retVal.setType(Bundle.BundleType.SEARCHSET);
|
||||
|
@ -104,19 +108,19 @@ public class EmpiProviderDstu3 extends BaseEmpiProvider {
|
|||
return retVal;
|
||||
}
|
||||
|
||||
private Bundle.BundleEntrySearchComponent toBundleEntrySearchComponent(MatchedTarget next) {
|
||||
private Bundle.BundleEntrySearchComponent toBundleEntrySearchComponent(MatchedTarget theMatchedTarget) {
|
||||
Bundle.BundleEntrySearchComponent searchComponent = new Bundle.BundleEntrySearchComponent();
|
||||
searchComponent.setMode(Bundle.SearchEntryMode.MATCH);
|
||||
searchComponent.setScore(next.getMatchResult().getNormalizedScore());
|
||||
searchComponent.setScore(theMatchedTarget.getMatchResult().getNormalizedScore());
|
||||
|
||||
MatchGrade matchGrade = MatchGrade.PROBABLE;
|
||||
if (next.isMatch()) {
|
||||
if (theMatchedTarget.isMatch()) {
|
||||
matchGrade = MatchGrade.CERTAIN;
|
||||
} else if (next.isPossibleMatch()) {
|
||||
} else if (theMatchedTarget.isPossibleMatch()) {
|
||||
matchGrade = MatchGrade.POSSIBLE;
|
||||
}
|
||||
searchComponent.addExtension("http://hl7.org/fhir/StructureDefinition/match-grade",
|
||||
new CodeType(matchGrade.toCode()));
|
||||
|
||||
searchComponent.addExtension(EmpiConstants.FIHR_STRUCTURE_DEF_MATCH_GRADE_URL_NAMESPACE, new CodeType(matchGrade.toCode()));
|
||||
return searchComponent;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ package ca.uhn.fhir.empi.provider;
|
|||
*/
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.empi.api.EmpiConstants;
|
||||
import ca.uhn.fhir.empi.api.EmpiLinkJson;
|
||||
import ca.uhn.fhir.empi.api.IEmpiControllerSvc;
|
||||
import ca.uhn.fhir.empi.api.IEmpiExpungeSvc;
|
||||
|
@ -54,6 +55,7 @@ import org.hl7.fhir.r4.model.StringType;
|
|||
import org.hl7.fhir.r4.model.codesystems.MatchGrade;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Stream;
|
||||
|
@ -85,6 +87,7 @@ public class EmpiProviderR4 extends BaseEmpiProvider {
|
|||
}
|
||||
|
||||
List<MatchedTarget> matches = myEmpiMatchFinderSvc.getMatchedTargets("Patient", thePatient);
|
||||
matches.sort(Comparator.comparing((MatchedTarget m) -> m.getMatchResult().getNormalizedScore()).reversed());
|
||||
|
||||
Bundle retVal = new Bundle();
|
||||
retVal.setType(Bundle.BundleType.SEARCHSET);
|
||||
|
@ -107,19 +110,19 @@ public class EmpiProviderR4 extends BaseEmpiProvider {
|
|||
return retVal;
|
||||
}
|
||||
|
||||
private Bundle.BundleEntrySearchComponent toBundleEntrySearchComponent(MatchedTarget next) {
|
||||
private Bundle.BundleEntrySearchComponent toBundleEntrySearchComponent(MatchedTarget theMatchedTarget) {
|
||||
Bundle.BundleEntrySearchComponent searchComponent = new Bundle.BundleEntrySearchComponent();
|
||||
searchComponent.setMode(Bundle.SearchEntryMode.MATCH);
|
||||
searchComponent.setScore(next.getMatchResult().getNormalizedScore());
|
||||
searchComponent.setScore(theMatchedTarget.getMatchResult().getNormalizedScore());
|
||||
|
||||
MatchGrade matchGrade = MatchGrade.PROBABLE;
|
||||
if (next.isMatch()) {
|
||||
if (theMatchedTarget.isMatch()) {
|
||||
matchGrade = MatchGrade.CERTAIN;
|
||||
} else if (next.isPossibleMatch()) {
|
||||
} else if (theMatchedTarget.isPossibleMatch()) {
|
||||
matchGrade = MatchGrade.POSSIBLE;
|
||||
}
|
||||
searchComponent.addExtension("http://hl7.org/fhir/StructureDefinition/match-grade",
|
||||
new CodeType(matchGrade.toCode()));
|
||||
|
||||
searchComponent.addExtension(EmpiConstants.FIHR_STRUCTURE_DEF_MATCH_GRADE_URL_NAMESPACE, new CodeType(matchGrade.toCode()));
|
||||
return searchComponent;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
package ca.uhn.fhir.empi.api;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class EmpiMatchOutcomeTest {
|
||||
|
||||
@Test
|
||||
void testNormalizedScore() {
|
||||
EmpiMatchOutcome outcome = new EmpiMatchOutcome(0l, 0.0);
|
||||
assertEquals(0.0, outcome.getNormalizedScore());
|
||||
|
||||
outcome = new EmpiMatchOutcome(10l, 10.0);
|
||||
assertEquals(1.0, outcome.getNormalizedScore());
|
||||
|
||||
outcome = new EmpiMatchOutcome(10l, -10.0);
|
||||
assertEquals(0.0, outcome.getNormalizedScore());
|
||||
|
||||
outcome = new EmpiMatchOutcome(3l, 2.0);
|
||||
assertEquals(2.0 / 3.0, outcome.getNormalizedScore(), 0.0001);
|
||||
|
||||
outcome = new EmpiMatchOutcome(5l, 19.0);
|
||||
assertEquals(1.0, outcome.getNormalizedScore());
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue