Merge pull request #2872 from hapifhir/issue-2871-enhance-mdm-expansion
Add MDM expansion by golden pid
This commit is contained in:
commit
a89798ad87
|
@ -75,6 +75,7 @@ public enum VersionEnum {
|
||||||
V5_4_1,
|
V5_4_1,
|
||||||
V5_4_2,
|
V5_4_2,
|
||||||
V5_5_0,
|
V5_5_0,
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
||||||
public static VersionEnum latestVersion() {
|
public static VersionEnum latestVersion() {
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
type: add
|
||||||
|
issue: 2871
|
||||||
|
title: "Modified the behaviour of the `:mdm` param qualifier. Previously, it used to only resolve IDs if the resource ID was a source resource.
|
||||||
|
Now, MDM expansion will work if you pass it the ID of a golden resource instead."
|
|
@ -67,4 +67,7 @@ public interface IMdmLinkDao extends JpaRepository<MdmLink, Long> {
|
||||||
"AND ml.myMatchResult=:matchResult")
|
"AND ml.myMatchResult=:matchResult")
|
||||||
List<MdmPidTuple> expandPidsBySourcePidAndMatchResult(@Param("sourcePid") Long theSourcePid, @Param("matchResult") MdmMatchResultEnum theMdmMatchResultEnum);
|
List<MdmPidTuple> expandPidsBySourcePidAndMatchResult(@Param("sourcePid") Long theSourcePid, @Param("matchResult") MdmMatchResultEnum theMdmMatchResultEnum);
|
||||||
|
|
||||||
|
@Query("SELECT ml.myGoldenResourcePid as goldenPid, ml.mySourcePid as sourcePid FROM MdmLink ml WHERE ml.myGoldenResourcePid = :goldenPid and ml.myMatchResult = :matchResult")
|
||||||
|
List<MdmPidTuple> expandPidsByGoldenResourcePidAndMatchResult(@Param("goldenPid") Long theSourcePid, @Param("matchResult") MdmMatchResultEnum theMdmMatchResultEnum);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,15 +25,13 @@ import ca.uhn.fhir.jpa.dao.index.IdHelperService;
|
||||||
import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
|
import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
|
||||||
import ca.uhn.fhir.mdm.log.Logs;
|
import ca.uhn.fhir.mdm.log.Logs;
|
||||||
import ca.uhn.fhir.model.primitive.IdDt;
|
import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
|
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
import org.hl7.fhir.instance.model.api.IIdType;
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import javax.annotation.Nonnull;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -82,14 +80,50 @@ public class MdmLinkExpandSvc {
|
||||||
public Set<String> expandMdmBySourceResourcePid(Long theSourceResourcePid) {
|
public Set<String> expandMdmBySourceResourcePid(Long theSourceResourcePid) {
|
||||||
ourLog.debug("About to expand source resource with PID {}", theSourceResourcePid);
|
ourLog.debug("About to expand source resource with PID {}", theSourceResourcePid);
|
||||||
List<IMdmLinkDao.MdmPidTuple> goldenPidSourcePidTuples = myMdmLinkDao.expandPidsBySourcePidAndMatchResult(theSourceResourcePid, MdmMatchResultEnum.MATCH);
|
List<IMdmLinkDao.MdmPidTuple> goldenPidSourcePidTuples = myMdmLinkDao.expandPidsBySourcePidAndMatchResult(theSourceResourcePid, MdmMatchResultEnum.MATCH);
|
||||||
|
return flattenPidTuplesToSet(theSourceResourcePid, goldenPidSourcePidTuples);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a PID of a golden resource, perform MDM expansion and return all the resource IDs of all resources that are
|
||||||
|
* MDM-Matched to this golden resource.
|
||||||
|
*
|
||||||
|
* @param theGoldenResourcePid The PID of the golden resource to MDM-Expand.
|
||||||
|
* @return A set of strings representing the FHIR ids of the expanded resources.
|
||||||
|
*/
|
||||||
|
public Set<String> expandMdmByGoldenResourceId(Long theGoldenResourcePid) {
|
||||||
|
ourLog.debug("About to expand golden resource with PID {}", theGoldenResourcePid);
|
||||||
|
List<IMdmLinkDao.MdmPidTuple> goldenPidSourcePidTuples = myMdmLinkDao.expandPidsByGoldenResourcePidAndMatchResult(theGoldenResourcePid, MdmMatchResultEnum.MATCH);
|
||||||
|
return flattenPidTuplesToSet(theGoldenResourcePid, goldenPidSourcePidTuples);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a resource ID of a golden resource, perform MDM expansion and return all the resource IDs of all resources that are
|
||||||
|
* MDM-Matched to this golden resource.
|
||||||
|
*
|
||||||
|
* @param theGoldenResourcePid The resource ID of the golden resource to MDM-Expand.
|
||||||
|
* @return A set of strings representing the FHIR ids of the expanded resources.
|
||||||
|
*/
|
||||||
|
public Set<String> expandMdmByGoldenResourcePid(Long theGoldenResourcePid) {
|
||||||
|
ourLog.debug("About to expand golden resource with PID {}", theGoldenResourcePid);
|
||||||
|
List<IMdmLinkDao.MdmPidTuple> goldenPidSourcePidTuples = myMdmLinkDao.expandPidsByGoldenResourcePidAndMatchResult(theGoldenResourcePid, MdmMatchResultEnum.MATCH);
|
||||||
|
return flattenPidTuplesToSet(theGoldenResourcePid, goldenPidSourcePidTuples);
|
||||||
|
}
|
||||||
|
public Set<String> expandMdmByGoldenResourceId(IdDt theId) {
|
||||||
|
ourLog.debug("About to expand golden resource with golden resource id {}", theId);
|
||||||
|
Long pidOrThrowException = myIdHelperService.getPidOrThrowException(theId);
|
||||||
|
return expandMdmByGoldenResourcePid(pidOrThrowException);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
private Set<String> flattenPidTuplesToSet(Long initialPid, List<IMdmLinkDao.MdmPidTuple> goldenPidSourcePidTuples) {
|
||||||
Set<Long> flattenedPids = new HashSet<>();
|
Set<Long> flattenedPids = new HashSet<>();
|
||||||
goldenPidSourcePidTuples.forEach(tuple -> {
|
goldenPidSourcePidTuples.forEach(tuple -> {
|
||||||
flattenedPids.add(tuple.getSourcePid());
|
flattenedPids.add(tuple.getSourcePid());
|
||||||
flattenedPids.add(tuple.getGoldenPid());
|
flattenedPids.add(tuple.getGoldenPid());
|
||||||
});
|
});
|
||||||
Set<String> resourceIds = myIdHelperService.translatePidsToFhirResourceIds(flattenedPids);
|
Set<String> resourceIds = myIdHelperService.translatePidsToFhirResourceIds(flattenedPids);
|
||||||
ourLog.debug("Pid {} has been expanded to [{}]", theSourceResourcePid, String.join(",", resourceIds));
|
ourLog.debug("Pid {} has been expanded to [{}]", initialPid, String.join(",", resourceIds));
|
||||||
return resourceIds;
|
return resourceIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,8 +76,16 @@ public class MdmSearchExpandingInterceptor {
|
||||||
if (iQueryParameterType instanceof ReferenceParam) {
|
if (iQueryParameterType instanceof ReferenceParam) {
|
||||||
ReferenceParam refParam = (ReferenceParam) iQueryParameterType;
|
ReferenceParam refParam = (ReferenceParam) iQueryParameterType;
|
||||||
if (refParam.isMdmExpand()) {
|
if (refParam.isMdmExpand()) {
|
||||||
ourLog.debug("Found a reference parameter to expand: {}", refParam.toString());
|
ourLog.debug("Found a reference parameter to expand: {}", refParam);
|
||||||
|
//First, attempt to expand as a source resource.
|
||||||
Set<String> expandedResourceIds = myMdmLinkExpandSvc.expandMdmBySourceResourceId(new IdDt(refParam.getValue()));
|
Set<String> expandedResourceIds = myMdmLinkExpandSvc.expandMdmBySourceResourceId(new IdDt(refParam.getValue()));
|
||||||
|
|
||||||
|
// If we failed, attempt to expand as a golden resource
|
||||||
|
if (expandedResourceIds.isEmpty()) {
|
||||||
|
expandedResourceIds = myMdmLinkExpandSvc.expandMdmByGoldenResourceId(new IdDt(refParam.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
//Rebuild the search param list.
|
||||||
if (!expandedResourceIds.isEmpty()) {
|
if (!expandedResourceIds.isEmpty()) {
|
||||||
ourLog.debug("Parameter has been expanded to: {}", String.join(", ", expandedResourceIds));
|
ourLog.debug("Parameter has been expanded to: {}", String.join(", ", expandedResourceIds));
|
||||||
toRemove.add(refParam);
|
toRemove.add(refParam);
|
||||||
|
|
|
@ -2,14 +2,18 @@ package ca.uhn.fhir.jpa.mdm.interceptor;
|
||||||
|
|
||||||
import ca.uhn.fhir.jpa.api.config.DaoConfig;
|
import ca.uhn.fhir.jpa.api.config.DaoConfig;
|
||||||
import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome;
|
import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome;
|
||||||
|
import ca.uhn.fhir.jpa.entity.MdmLink;
|
||||||
import ca.uhn.fhir.jpa.mdm.BaseMdmR4Test;
|
import ca.uhn.fhir.jpa.mdm.BaseMdmR4Test;
|
||||||
import ca.uhn.fhir.jpa.mdm.helper.MdmHelperConfig;
|
import ca.uhn.fhir.jpa.mdm.helper.MdmHelperConfig;
|
||||||
import ca.uhn.fhir.jpa.mdm.helper.MdmHelperR4;
|
import ca.uhn.fhir.jpa.mdm.helper.MdmHelperR4;
|
||||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||||
import ca.uhn.fhir.mdm.api.MdmConstants;
|
import ca.uhn.fhir.mdm.api.MdmConstants;
|
||||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||||
|
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
|
||||||
import ca.uhn.fhir.rest.param.ReferenceOrListParam;
|
import ca.uhn.fhir.rest.param.ReferenceOrListParam;
|
||||||
import ca.uhn.fhir.rest.param.ReferenceParam;
|
import ca.uhn.fhir.rest.param.ReferenceParam;
|
||||||
|
import org.elasticsearch.common.collect.Set;
|
||||||
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
import org.hl7.fhir.r4.model.CodeableConcept;
|
import org.hl7.fhir.r4.model.CodeableConcept;
|
||||||
import org.hl7.fhir.r4.model.Observation;
|
import org.hl7.fhir.r4.model.Observation;
|
||||||
import org.hl7.fhir.r4.model.Patient;
|
import org.hl7.fhir.r4.model.Patient;
|
||||||
|
@ -21,6 +25,8 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.test.annotation.DirtiesContext;
|
import org.springframework.test.annotation.DirtiesContext;
|
||||||
import org.springframework.test.context.ContextConfiguration;
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
|
@ -73,6 +79,19 @@ public class MdmSearchExpandingInterceptorIT extends BaseMdmR4Test {
|
||||||
myDaoConfig.setAllowMdmExpansion(true);
|
myDaoConfig.setAllowMdmExpansion(true);
|
||||||
search = myObservationDao.search(searchParameterMap);
|
search = myObservationDao.search(searchParameterMap);
|
||||||
assertThat(search.size(), is(equalTo(4)));
|
assertThat(search.size(), is(equalTo(4)));
|
||||||
|
List<MdmLink> all = myMdmLinkDao.findAll();
|
||||||
|
Long goldenPid = all.get(0).getGoldenResourcePid();
|
||||||
|
IIdType goldenId = myIdHelperService.translatePidIdToForcedId(myFhirContext, "Patient", new ResourcePersistentId(goldenPid));
|
||||||
|
//Verify that expansion by the golden resource id resolves down to everything its links have.
|
||||||
|
|
||||||
|
SearchParameterMap goldenSpMap = new SearchParameterMap();
|
||||||
|
goldenSpMap.setLoadSynchronous(true);
|
||||||
|
ReferenceOrListParam goldenReferenceOrListParam = new ReferenceOrListParam();
|
||||||
|
goldenReferenceOrListParam.addOr(new ReferenceParam(goldenId).setMdmExpand(true));
|
||||||
|
goldenSpMap.add(Observation.SP_SUBJECT, goldenReferenceOrListParam);
|
||||||
|
|
||||||
|
search = myObservationDao.search(goldenSpMap);
|
||||||
|
assertThat(search.size(), is(equalTo(4)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
Loading…
Reference in New Issue