Jd 20240614 6010 bundle entry search score missing (#6011)
* 6010 test * 6010 add bundle entry search score * 6010 support other fhir versions for search score * 6010 changelog * 6116 mvn spotless * 6010 address code review comments --------- Co-authored-by: jdar <justin.dar@smiledigitalhealth.com>
This commit is contained in:
parent
bce0313458
commit
11d61a5f72
|
@ -31,6 +31,7 @@ import org.hl7.fhir.instance.model.api.IBaseResource;
|
|||
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -80,6 +81,15 @@ public abstract class ResourceMetadataKeyEnum<T> implements Serializable {
|
|||
*/
|
||||
public static final ResourceMetadataKeyEnum<BundleEntrySearchModeEnum> ENTRY_SEARCH_MODE =
|
||||
new ResourceMetadataKeyEnum<>("ENTRY_SEARCH_MODE", BundleEntrySearchModeEnum.class) {};
|
||||
/**
|
||||
* If present and populated with a decimal value, contains the "bundle entry search score", which is the value of the status field in the Bundle entry containing this resource.
|
||||
* The value for this key corresponds to field <code>Bundle.entry.search.score</code>. This value represents the search ranking score, where 1.0 is relevant and 0.0 is irrelevant.
|
||||
* <p>
|
||||
* Note that status is only used in FHIR DSTU2 and later.
|
||||
* </p>
|
||||
*/
|
||||
public static final ResourceMetadataKeyEnum<BigDecimal> ENTRY_SEARCH_SCORE =
|
||||
new ResourceMetadataKeyEnum<>("ENTRY_SEARCH_SCORE", BigDecimal.class) {};
|
||||
/**
|
||||
* If present and populated with a {@link BundleEntryTransactionMethodEnum}, contains the "bundle entry transaction operation", which is the value of the status field in the Bundle entry
|
||||
* containing this resource. The value for this key corresponds to field <code>Bundle.entry.transaction.operation</code>. This value can be set in resources being transmitted to a server to
|
||||
|
|
|
@ -50,6 +50,7 @@ import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
|
@ -578,42 +579,53 @@ public class BundleUtil {
|
|||
BaseRuntimeElementCompositeDefinition<?> searchChildContentsDef =
|
||||
(BaseRuntimeElementCompositeDefinition<?>) searchChildDef.getChildByName("search");
|
||||
BaseRuntimeChildDefinition searchModeChildDef = searchChildContentsDef.getChildByName("mode");
|
||||
BaseRuntimeChildDefinition searchScoreChildDef = searchChildContentsDef.getChildByName("score");
|
||||
|
||||
List<SearchBundleEntryParts> retVal = new ArrayList<>();
|
||||
for (IBase nextEntry : entries) {
|
||||
SearchBundleEntryParts parts = getSearchBundleEntryParts(
|
||||
fullUrlChildDef, resourceChildDef, searchChildDef, searchModeChildDef, nextEntry);
|
||||
fullUrlChildDef,
|
||||
resourceChildDef,
|
||||
searchChildDef,
|
||||
searchModeChildDef,
|
||||
searchScoreChildDef,
|
||||
nextEntry);
|
||||
retVal.add(parts);
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
private static SearchBundleEntryParts getSearchBundleEntryParts(
|
||||
BaseRuntimeChildDefinition fullUrlChildDef,
|
||||
BaseRuntimeChildDefinition resourceChildDef,
|
||||
BaseRuntimeChildDefinition searchChildDef,
|
||||
BaseRuntimeChildDefinition searchModeChildDef,
|
||||
BaseRuntimeChildDefinition theFullUrlChildDef,
|
||||
BaseRuntimeChildDefinition theResourceChildDef,
|
||||
BaseRuntimeChildDefinition theSearchChildDef,
|
||||
BaseRuntimeChildDefinition theSearchModeChildDef,
|
||||
BaseRuntimeChildDefinition theSearchScoreChildDef,
|
||||
IBase entry) {
|
||||
IBaseResource resource = null;
|
||||
String matchMode = null;
|
||||
BigDecimal searchScore = null;
|
||||
|
||||
String fullUrl = fullUrlChildDef
|
||||
String fullUrl = theFullUrlChildDef
|
||||
.getAccessor()
|
||||
.getFirstValueOrNull(entry)
|
||||
.map(t -> ((IPrimitiveType<?>) t).getValueAsString())
|
||||
.orElse(null);
|
||||
|
||||
for (IBase nextResource : resourceChildDef.getAccessor().getValues(entry)) {
|
||||
for (IBase nextResource : theResourceChildDef.getAccessor().getValues(entry)) {
|
||||
resource = (IBaseResource) nextResource;
|
||||
}
|
||||
|
||||
for (IBase nextSearch : searchChildDef.getAccessor().getValues(entry)) {
|
||||
for (IBase nextUrl : searchModeChildDef.getAccessor().getValues(nextSearch)) {
|
||||
for (IBase nextSearch : theSearchChildDef.getAccessor().getValues(entry)) {
|
||||
for (IBase nextUrl : theSearchModeChildDef.getAccessor().getValues(nextSearch)) {
|
||||
matchMode = ((IPrimitiveType<?>) nextUrl).getValueAsString();
|
||||
}
|
||||
for (IBase nextUrl : theSearchScoreChildDef.getAccessor().getValues(nextSearch)) {
|
||||
searchScore = (BigDecimal) ((IPrimitiveType<?>) nextUrl).getValue();
|
||||
}
|
||||
}
|
||||
|
||||
return new SearchBundleEntryParts(fullUrl, resource, matchMode);
|
||||
return new SearchBundleEntryParts(fullUrl, resource, matchMode, searchScore);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -22,15 +22,20 @@ package ca.uhn.fhir.util.bundle;
|
|||
import ca.uhn.fhir.model.valueset.BundleEntrySearchModeEnum;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
public class SearchBundleEntryParts {
|
||||
private final IBaseResource myResource;
|
||||
private final BundleEntrySearchModeEnum mySearchMode;
|
||||
private final BigDecimal mySearchScore;
|
||||
private final String myFullUrl;
|
||||
|
||||
public SearchBundleEntryParts(String theFullUrl, IBaseResource theResource, String theSearchMode) {
|
||||
public SearchBundleEntryParts(
|
||||
String theFullUrl, IBaseResource theResource, String theSearchMode, BigDecimal theSearchScore) {
|
||||
myFullUrl = theFullUrl;
|
||||
myResource = theResource;
|
||||
mySearchMode = BundleEntrySearchModeEnum.forCode(theSearchMode);
|
||||
mySearchScore = theSearchScore;
|
||||
}
|
||||
|
||||
public String getFullUrl() {
|
||||
|
@ -44,4 +49,8 @@ public class SearchBundleEntryParts {
|
|||
public BundleEntrySearchModeEnum getSearchMode() {
|
||||
return mySearchMode;
|
||||
}
|
||||
|
||||
public BigDecimal getSearchScore() {
|
||||
return mySearchScore;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
type: add
|
||||
issue: 6010
|
||||
jira: SMILE-8214
|
||||
title: "When populated, the search score field will now be included in the entries of a response Bundle."
|
|
@ -43,6 +43,7 @@ import org.hl7.fhir.instance.model.api.IBaseResource;
|
|||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
|
@ -148,10 +149,15 @@ public class Dstu2_1BundleFactory implements IVersionSpecificBundleFactory {
|
|||
}
|
||||
}
|
||||
|
||||
// Populate Bundle.entry.search
|
||||
BundleEntrySearchModeEnum searchMode = ResourceMetadataKeyEnum.ENTRY_SEARCH_MODE.get(nextAsResource);
|
||||
if (searchMode != null) {
|
||||
entry.getSearch().getModeElement().setValueAsString(searchMode.getCode());
|
||||
}
|
||||
BigDecimal searchScore = ResourceMetadataKeyEnum.ENTRY_SEARCH_SCORE.get(nextAsResource);
|
||||
if (searchScore != null) {
|
||||
entry.getSearch().getScoreElement().setValue(searchScore);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -41,6 +41,7 @@ import jakarta.annotation.Nonnull;
|
|||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
|
@ -138,10 +139,15 @@ public class Dstu2BundleFactory implements IVersionSpecificBundleFactory {
|
|||
}
|
||||
populateBundleEntryFullUrl(next, entry);
|
||||
|
||||
// Populate Bundle.entry.search
|
||||
BundleEntrySearchModeEnum searchMode = ResourceMetadataKeyEnum.ENTRY_SEARCH_MODE.get(next);
|
||||
if (searchMode != null) {
|
||||
entry.getSearch().getModeElement().setValue(searchMode.getCode());
|
||||
}
|
||||
BigDecimal searchScore = ResourceMetadataKeyEnum.ENTRY_SEARCH_SCORE.get(next);
|
||||
if (searchScore != null) {
|
||||
entry.getSearch().getScoreElement().setValue(searchScore);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -44,6 +44,7 @@ import org.hl7.fhir.instance.model.api.IBaseResource;
|
|||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
|
@ -173,6 +174,10 @@ public class Dstu3BundleFactory implements IVersionSpecificBundleFactory {
|
|||
if (searchMode != null) {
|
||||
entry.getSearch().getModeElement().setValueAsString(searchMode.getCode());
|
||||
}
|
||||
BigDecimal searchScore = ResourceMetadataKeyEnum.ENTRY_SEARCH_SCORE.get(nextAsResource);
|
||||
if (searchScore != null) {
|
||||
entry.getSearch().getScoreElement().setValue(searchScore);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -45,6 +45,7 @@ import org.hl7.fhir.instance.model.api.IBaseResource;
|
|||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
|
@ -178,6 +179,10 @@ public class Dstu2Hl7OrgBundleFactory implements IVersionSpecificBundleFactory {
|
|||
if (searchMode != null) {
|
||||
entry.getSearch().getModeElement().setValueAsString(searchMode.getCode());
|
||||
}
|
||||
BigDecimal searchScore = ResourceMetadataKeyEnum.ENTRY_SEARCH_SCORE.get(nextAsResource);
|
||||
if (searchScore != null) {
|
||||
entry.getSearch().getScoreElement().setValue(searchScore);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -45,6 +45,7 @@ import org.hl7.fhir.r4.model.DomainResource;
|
|||
import org.hl7.fhir.r4.model.IdType;
|
||||
import org.hl7.fhir.r4.model.Resource;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
|
@ -181,6 +182,10 @@ public class R4BundleFactory implements IVersionSpecificBundleFactory {
|
|||
if (searchMode != null) {
|
||||
entry.getSearch().getModeElement().setValueAsString(searchMode.getCode());
|
||||
}
|
||||
BigDecimal searchScore = ResourceMetadataKeyEnum.ENTRY_SEARCH_SCORE.get(nextAsResource);
|
||||
if (searchScore != null) {
|
||||
entry.getSearch().getScoreElement().setValue(searchScore);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -30,6 +30,7 @@ import org.junit.jupiter.api.Test;
|
|||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.CsvSource;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
@ -550,6 +551,55 @@ public class BundleUtilTest {
|
|||
assertNotNull(searchBundleEntryParts.get(0).getResource());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConvertingToSearchBundleEntryPartsReturnsScore() {
|
||||
|
||||
//Given
|
||||
String bundleString = """
|
||||
{
|
||||
"resourceType": "Bundle",
|
||||
"id": "bd194b7f-ac1e-429a-a206-ee2c470f23b5",
|
||||
"type": "searchset",
|
||||
"total": 1,
|
||||
"link": [
|
||||
{
|
||||
"relation": "self",
|
||||
"url": "http://localhost:8000/Condition?_count=1"
|
||||
}
|
||||
],
|
||||
"entry": [
|
||||
{
|
||||
"fullUrl": "http://localhost:8000/Condition/1626",
|
||||
"resource": {
|
||||
"resourceType": "Condition",
|
||||
"id": "1626",
|
||||
"identifier": [
|
||||
{
|
||||
"system": "urn:hssc:musc:conditionid",
|
||||
"value": "1064115000.1.5"
|
||||
}
|
||||
]
|
||||
},
|
||||
"search": {
|
||||
"mode": "match",
|
||||
"score": 1
|
||||
}
|
||||
}
|
||||
]
|
||||
}""";
|
||||
Bundle bundle = ourCtx.newJsonParser().parseResource(Bundle.class, bundleString);
|
||||
|
||||
//When
|
||||
List<SearchBundleEntryParts> searchBundleEntryParts = BundleUtil.getSearchBundleEntryParts(ourCtx, bundle);
|
||||
|
||||
//Then
|
||||
assertThat(searchBundleEntryParts).hasSize(1);
|
||||
assertEquals(BundleEntrySearchModeEnum.MATCH, searchBundleEntryParts.get(0).getSearchMode());
|
||||
assertEquals(new BigDecimal(1), searchBundleEntryParts.get(0).getSearchScore());
|
||||
assertThat(searchBundleEntryParts.get(0).getFullUrl()).contains("Condition/1626");
|
||||
assertNotNull(searchBundleEntryParts.get(0).getResource());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransactionSorterReturnsDeletesInCorrectProcessingOrder() {
|
||||
Bundle b = new Bundle();
|
||||
|
|
|
@ -44,6 +44,7 @@ import org.hl7.fhir.r4b.model.DomainResource;
|
|||
import org.hl7.fhir.r4b.model.IdType;
|
||||
import org.hl7.fhir.r4b.model.Resource;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
|
@ -177,6 +178,10 @@ public class R4BBundleFactory implements IVersionSpecificBundleFactory {
|
|||
if (searchMode != null) {
|
||||
entry.getSearch().getModeElement().setValueAsString(searchMode.getCode());
|
||||
}
|
||||
BigDecimal searchScore = ResourceMetadataKeyEnum.ENTRY_SEARCH_SCORE.get(nextAsResource);
|
||||
if (searchScore != null) {
|
||||
entry.getSearch().getScoreElement().setValue(searchScore);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -44,6 +44,7 @@ import org.hl7.fhir.r5.model.DomainResource;
|
|||
import org.hl7.fhir.r5.model.IdType;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
|
@ -177,6 +178,10 @@ public class R5BundleFactory implements IVersionSpecificBundleFactory {
|
|||
if (searchMode != null) {
|
||||
entry.getSearch().getModeElement().setValueAsString(searchMode.getCode());
|
||||
}
|
||||
BigDecimal searchScore = ResourceMetadataKeyEnum.ENTRY_SEARCH_SCORE.get(nextAsResource);
|
||||
if (searchScore != null) {
|
||||
entry.getSearch().getScoreElement().setValue(searchScore);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue