Perf updates possibly working?

This commit is contained in:
James Agnew 2017-04-10 16:29:24 -04:00
parent aa02dd5037
commit 0a8900ee78
5 changed files with 152 additions and 37 deletions

View File

@ -143,7 +143,7 @@ public class SearchBuilder {
Join<ResourceTable, ResourceIndexedSearchParamDate> join = myResourceTableRoot.join("myParamsDate", JoinType.LEFT); Join<ResourceTable, ResourceIndexedSearchParamDate> join = myResourceTableRoot.join("myParamsDate", JoinType.LEFT);
if (theList.get(0).getMissing() != null) { if (theList.get(0).getMissing() != null) {
addPredicateParamMissing(theParamName, theList.get(0).getMissing(), join); addPredicateParamMissing(theResourceName, theParamName, theList.get(0).getMissing(), join);
return; return;
} }
@ -269,7 +269,7 @@ public class SearchBuilder {
Join<ResourceTable, ResourceIndexedSearchParamNumber> join = myResourceTableRoot.join("myParamsNumber", JoinType.LEFT); Join<ResourceTable, ResourceIndexedSearchParamNumber> join = myResourceTableRoot.join("myParamsNumber", JoinType.LEFT);
if (theList.get(0).getMissing() != null) { if (theList.get(0).getMissing() != null) {
addPredicateParamMissing(theParamName, theList.get(0).getMissing(), join); addPredicateParamMissing(theResourceName, theParamName, theList.get(0).getMissing(), join);
return; return;
} }
@ -302,18 +302,18 @@ public class SearchBuilder {
myPredicates.add(myBuilder.or(toArray(codePredicates))); myPredicates.add(myBuilder.or(toArray(codePredicates)));
} }
private void addPredicateParamMissing(String theParamName, boolean theMissing, Join<ResourceTable, ? extends BaseResourceIndexedSearchParam> theJoin) { private void addPredicateParamMissing(String theResourceName, String theParamName, boolean theMissing, Join<ResourceTable, ? extends BaseResourceIndexedSearchParam> theJoin) {
myPredicates.add(myBuilder.equal(theJoin.get("myResourceType"), myResourceName)); myPredicates.add(myBuilder.equal(theJoin.get("myResourceType"), theResourceName));
myPredicates.add(myBuilder.equal(theJoin.get("myParamName"), theParamName)); myPredicates.add(myBuilder.equal(theJoin.get("myParamName"), theParamName));
myPredicates.add(myBuilder.equal(theJoin.get("myMissing"), theMissing)); myPredicates.add(myBuilder.equal(theJoin.get("myMissing"), theMissing));
} }
private void addPredicateParamMissing(String theParamName, boolean theMissing) { private void addPredicateParamMissing(String theResourceName, String theParamName, boolean theMissing) {
Join<ResourceTable, SearchParamPresent> paramPresentJoin = myResourceTableRoot.join("mySearchParamPresents", JoinType.LEFT); Join<ResourceTable, SearchParamPresent> paramPresentJoin = myResourceTableRoot.join("mySearchParamPresents", JoinType.LEFT);
Join<SearchParamPresent, SearchParam> paramJoin = paramPresentJoin.join("mySearchParam", JoinType.LEFT); Join<SearchParamPresent, SearchParam> paramJoin = paramPresentJoin.join("mySearchParam", JoinType.LEFT);
myPredicates.add(myBuilder.equal(paramJoin.get("myResourceName"), myResourceName)); myPredicates.add(myBuilder.equal(paramJoin.get("myResourceName"), theResourceName));
myPredicates.add(myBuilder.equal(paramJoin.get("myParamName"), theParamName)); myPredicates.add(myBuilder.equal(paramJoin.get("myParamName"), theParamName));
myPredicates.add(myBuilder.equal(paramPresentJoin.get("myPresent"), !theMissing)); myPredicates.add(myBuilder.equal(paramPresentJoin.get("myPresent"), !theMissing));
} }
@ -322,7 +322,7 @@ public class SearchBuilder {
Join<ResourceTable, ResourceIndexedSearchParamQuantity> join = myResourceTableRoot.join("myParamsQuantity", JoinType.LEFT); Join<ResourceTable, ResourceIndexedSearchParamQuantity> join = myResourceTableRoot.join("myParamsQuantity", JoinType.LEFT);
if (theList.get(0).getMissing() != null) { if (theList.get(0).getMissing() != null) {
addPredicateParamMissing(theParamName, theList.get(0).getMissing(), join); addPredicateParamMissing(theResourceName, theParamName, theList.get(0).getMissing(), join);
return; return;
} }
@ -336,11 +336,14 @@ public class SearchBuilder {
myPredicates.add(myBuilder.or(toArray(codePredicates))); myPredicates.add(myBuilder.or(toArray(codePredicates)));
} }
private void addPredicateReference(String theParamName, List<? extends IQueryParameterType> theList) { /**
* Add reference predicate to the current search
*/
private void addPredicateReference(String theResourceName, String theParamName, List<? extends IQueryParameterType> theList) {
assert theParamName.contains(".") == false; assert theParamName.contains(".") == false;
if (theList.get(0).getMissing() != null) { if (theList.get(0).getMissing() != null) {
addPredicateParamMissing(theParamName, theList.get(0).getMissing()); addPredicateParamMissing(theResourceName, theParamName, theList.get(0).getMissing());
return; return;
} }
@ -377,8 +380,10 @@ public class SearchBuilder {
} }
for (Long next : targetPid) { for (Long next : targetPid) {
ourLog.debug("Searching for resource link with target PID: {}", next); ourLog.debug("Searching for resource link with target PID: {}", next);
Predicate eq = myBuilder.equal(join.get("myTargetResourcePid"), next);
codePredicates.add(eq); Predicate pathPredicate = createResourceLinkPathPredicate(theResourceName, theParamName, join);
Predicate pidPredicate = myBuilder.equal(join.get("myTargetResourcePid"), next);
codePredicates.add(myBuilder.and(pathPredicate, pidPredicate));
} }
} else { } else {
@ -469,7 +474,6 @@ public class SearchBuilder {
} }
foundChainMatch = true; foundChainMatch = true;
// Set<Long> pids = dao.searchForIds(chain, chainValue);
Subquery<Long> subQ = myResourceTableQuery.subquery(Long.class); Subquery<Long> subQ = myResourceTableQuery.subquery(Long.class);
Root<ResourceTable> subQfrom = subQ.from(ResourceTable.class); Root<ResourceTable> subQfrom = subQ.from(ResourceTable.class);
@ -501,8 +505,9 @@ public class SearchBuilder {
myResourceTableRoot = stackRoot; myResourceTableRoot = stackRoot;
myPredicates = stackPredicates; myPredicates = stackPredicates;
Predicate eq = join.get("myTargetResourcePid").in(subQ); Predicate pathPredicate = createResourceLinkPathPredicate(theResourceName, theParamName, join);
codePredicates.add(eq); Predicate pidPredicate = join.get("myTargetResourcePid").in(subQ);
codePredicates.add(myBuilder.and(pathPredicate, pidPredicate));
} }
@ -525,7 +530,7 @@ public class SearchBuilder {
Join<ResourceTable, ResourceIndexedSearchParamString> join = myResourceTableRoot.join("myParamsString", JoinType.LEFT); Join<ResourceTable, ResourceIndexedSearchParamString> join = myResourceTableRoot.join("myParamsString", JoinType.LEFT);
if (theList.get(0).getMissing() != null) { if (theList.get(0).getMissing() != null) {
addPredicateParamMissing(theParamName, theList.get(0).getMissing(), join); addPredicateParamMissing(theResourceName, theParamName, theList.get(0).getMissing(), join);
return; return;
} }
@ -673,7 +678,7 @@ public class SearchBuilder {
Join<ResourceTable, ResourceIndexedSearchParamToken> join = myResourceTableRoot.join("myParamsToken", JoinType.LEFT); Join<ResourceTable, ResourceIndexedSearchParamToken> join = myResourceTableRoot.join("myParamsToken", JoinType.LEFT);
if (theList.get(0).getMissing() != null) { if (theList.get(0).getMissing() != null) {
addPredicateParamMissing(theParamName, theList.get(0).getMissing(), join); addPredicateParamMissing(theResourceName, theParamName, theList.get(0).getMissing(), join);
return; return;
} }
@ -700,12 +705,12 @@ public class SearchBuilder {
myPredicates.add(spPredicate); myPredicates.add(spPredicate);
} }
private void addPredicateUri(String theParamName, List<? extends IQueryParameterType> theList) { private void addPredicateUri(String theResourceName, String theParamName, List<? extends IQueryParameterType> theList) {
Join<ResourceTable, ResourceIndexedSearchParamUri> join = myResourceTableRoot.join("myParamsUri", JoinType.LEFT); Join<ResourceTable, ResourceIndexedSearchParamUri> join = myResourceTableRoot.join("myParamsUri", JoinType.LEFT);
if (theList.get(0).getMissing() != null) { if (theList.get(0).getMissing() != null) {
addPredicateParamMissing(theParamName, theList.get(0).getMissing(), join); addPredicateParamMissing(theResourceName, theParamName, theList.get(0).getMissing(), join);
return; return;
} }
@ -1172,8 +1177,8 @@ public class SearchBuilder {
return combineParamIndexPredicateWithParamNamePredicate(theResourceName, theParamName, theFrom, singleCode); return combineParamIndexPredicateWithParamNamePredicate(theResourceName, theParamName, theFrom, singleCode);
} }
private Predicate createResourceLinkPathPredicate(String theParamName, From<?, ? extends ResourceLink> from) { private Predicate createResourceLinkPathPredicate(String theResourceName, String theParamName, From<?, ? extends ResourceLink> from) {
return createResourceLinkPathPredicate(myCallingDao, myContext, theParamName, from, myResourceType); return createResourceLinkPathPredicate(myCallingDao, myContext, theParamName, from, theResourceName);
} }
private TypedQuery<Long> createSearchAllByTypeQuery(DateRangeParam theLastUpdated) { private TypedQuery<Long> createSearchAllByTypeQuery(DateRangeParam theLastUpdated) {
@ -1750,7 +1755,7 @@ public class SearchBuilder {
break; break;
case REFERENCE: case REFERENCE:
for (List<? extends IQueryParameterType> nextAnd : theAndOrParams) { for (List<? extends IQueryParameterType> nextAnd : theAndOrParams) {
addPredicateReference(theParamName, nextAnd); addPredicateReference(theResourceName, theParamName, nextAnd);
} }
break; break;
case STRING: case STRING:
@ -1775,7 +1780,7 @@ public class SearchBuilder {
break; break;
case URI: case URI:
for (List<? extends IQueryParameterType> nextAnd : theAndOrParams) { for (List<? extends IQueryParameterType> nextAnd : theAndOrParams) {
addPredicateUri(theParamName, nextAnd); addPredicateUri(theResourceName, theParamName, nextAnd);
} }
break; break;
case HAS: case HAS:
@ -1915,12 +1920,12 @@ public class SearchBuilder {
return likeExpression.replace("%", "[%]") + "%"; return likeExpression.replace("%", "[%]") + "%";
} }
private static Predicate createResourceLinkPathPredicate(IDao theCallingDao, FhirContext theContext, String theParamName, From<?, ? extends ResourceLink> from, private static Predicate createResourceLinkPathPredicate(IDao theCallingDao, FhirContext theContext, String theParamName, From<?, ? extends ResourceLink> theFrom,
Class<? extends IBaseResource> resourceType) { String theResourceType) {
RuntimeResourceDefinition resourceDef = theContext.getResourceDefinition(resourceType); RuntimeResourceDefinition resourceDef = theContext.getResourceDefinition(theResourceType);
RuntimeSearchParam param = theCallingDao.getSearchParamByName(resourceDef, theParamName); RuntimeSearchParam param = theCallingDao.getSearchParamByName(resourceDef, theParamName);
List<String> path = param.getPathsSplit(); List<String> path = param.getPathsSplit();
Predicate type = from.get("mySourcePath").in(path); Predicate type = theFrom.get("mySourcePath").in(path);
return type; return type;
} }

View File

@ -24,6 +24,7 @@ import java.util.Set;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.hl7.fhir.dstu3.model.Task;
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.junit.AfterClass; import org.junit.AfterClass;
@ -106,6 +107,9 @@ import ca.uhn.fhir.util.TestUtil;
public class FhirResourceDaoDstu2SearchNoFtTest extends BaseJpaDstu2Test { public class FhirResourceDaoDstu2SearchNoFtTest extends BaseJpaDstu2Test {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoDstu2SearchNoFtTest.class); private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoDstu2SearchNoFtTest.class);
@Autowired
private ISearchParamPresentDao mySearchParamPresentDao;
@Test @Test
public void testCodeSearch() { public void testCodeSearch() {
Subscription subs = new Subscription(); Subscription subs = new Subscription();
@ -1264,15 +1268,12 @@ public class FhirResourceDaoDstu2SearchNoFtTest extends BaseJpaDstu2Test {
result = toList(myObservationDao.search(Observation.SP_SUBJECT, new ReferenceParam("testSearchResourceLinkWithTextLogicalId99"))); result = toList(myObservationDao.search(Observation.SP_SUBJECT, new ReferenceParam("testSearchResourceLinkWithTextLogicalId99")));
assertEquals(0, result.size()); assertEquals(0, result.size());
result = toList(myObservationDao.search(Observation.SP_SUBJECT, new ReferenceParam("999999999999999"))); result = toList(myObservationDao.search(Observation.SP_SUBJECT, new ReferenceParam("999999999999999")));
assertEquals(0, result.size()); assertEquals(0, result.size());
} }
@Autowired
private ISearchParamPresentDao mySearchParamPresentDao;
@SuppressWarnings("unused") @SuppressWarnings("unused")
@Test @Test
public void testSearchResourceReferenceMissing() { public void testSearchResourceReferenceMissing() {
@ -1311,7 +1312,7 @@ public class FhirResourceDaoDstu2SearchNoFtTest extends BaseJpaDstu2Test {
} }
ourLog.info("" + mySearchParamPresentDao.findAll()); ourLog.info("" + mySearchParamPresentDao.findAll());
SearchParameterMap params; SearchParameterMap params;
params = new SearchParameterMap(); params = new SearchParameterMap();
@ -1417,7 +1418,8 @@ public class FhirResourceDaoDstu2SearchNoFtTest extends BaseJpaDstu2Test {
Patient patient = new Patient(); Patient patient = new Patient();
patient.addIdentifier().setSystem("urn:system").setValue("testSearchTokenParam001"); patient.addIdentifier().setSystem("urn:system").setValue("testSearchTokenParam001");
patient.addName().addFamily("Tester").addGiven("testSearchTokenParam1"); patient.addName().addFamily("Tester").addGiven("testSearchTokenParam1");
patient.addCommunication().getLanguage().setText("testSearchTokenParamComText").addCoding().setCode("testSearchTokenParamCode").setSystem("testSearchTokenParamSystem").setDisplay("testSearchTokenParamDisplay"); patient.addCommunication().getLanguage().setText("testSearchTokenParamComText").addCoding().setCode("testSearchTokenParamCode").setSystem("testSearchTokenParamSystem")
.setDisplay("testSearchTokenParamDisplay");
myPatientDao.create(patient, mySrd); myPatientDao.create(patient, mySrd);
patient = new Patient(); patient = new Patient();

View File

@ -148,6 +148,9 @@ public abstract class BaseJpaDstu3Test extends BaseJpaTest {
@Qualifier("myOrganizationDaoDstu3") @Qualifier("myOrganizationDaoDstu3")
protected IFhirResourceDao<Organization> myOrganizationDao; protected IFhirResourceDao<Organization> myOrganizationDao;
@Autowired @Autowired
@Qualifier("myTaskDaoDstu3")
protected IFhirResourceDao<Task> myTaskDao;
@Autowired
@Qualifier("myPatientDaoDstu3") @Qualifier("myPatientDaoDstu3")
protected IFhirResourceDaoPatient<Patient> myPatientDao; protected IFhirResourceDaoPatient<Patient> myPatientDao;
@Autowired @Autowired

View File

@ -20,6 +20,7 @@ import org.junit.Test;
import ca.uhn.fhir.jpa.dao.SearchParameterMap; import ca.uhn.fhir.jpa.dao.SearchParameterMap;
import ca.uhn.fhir.rest.param.TokenParam; import ca.uhn.fhir.rest.param.TokenParam;
import ca.uhn.fhir.rest.server.IBundleProvider; import ca.uhn.fhir.rest.server.IBundleProvider;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException; import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import ca.uhn.fhir.util.TestUtil; import ca.uhn.fhir.util.TestUtil;
@ -238,8 +239,12 @@ public class FhirResourceDaoDstu3SearchCustomSearchParamTest extends BaseJpaDstu
// Try with custom gender SP // Try with custom gender SP
map = new SearchParameterMap(); map = new SearchParameterMap();
map.add("foo", new TokenParam(null, "male")); map.add("foo", new TokenParam(null, "male"));
IBundleProvider res = myPatientDao.search(map); try {
assertEquals(0, res.size()); myPatientDao.search(map);
fail();
} catch (InvalidRequestException e) {
assertEquals("Unknown search parameter foo for resource type Patient", e.getMessage());
}
} }
@Test @Test
@ -272,9 +277,12 @@ public class FhirResourceDaoDstu3SearchCustomSearchParamTest extends BaseJpaDstu
// Try with custom gender SP (should find nothing) // Try with custom gender SP (should find nothing)
map = new SearchParameterMap(); map = new SearchParameterMap();
map.add("foo", new TokenParam(null, "male")); map.add("foo", new TokenParam(null, "male"));
results = myPatientDao.search(map); try {
foundResources = toUnqualifiedVersionlessIdValues(results); myPatientDao.search(map);
assertThat(foundResources, empty()); fail();
} catch (InvalidRequestException e) {
assertEquals("Unknown search parameter foo for resource type Patient", e.getMessage());
}
// Try with normal gender SP // Try with normal gender SP
map = new SearchParameterMap(); map = new SearchParameterMap();

View File

@ -85,6 +85,103 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
myDaoConfig.setExpireSearchResultsAfterMillis(new DaoConfig().getExpireSearchResultsAfterMillis()); myDaoConfig.setExpireSearchResultsAfterMillis(new DaoConfig().getExpireSearchResultsAfterMillis());
} }
@SuppressWarnings("unused")
@Test
public void testSearchResourceReferenceOnlyCorrectPath() {
IIdType oid1;
{
Organization org = new Organization();
org.setActive(true);
oid1 = myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless();
}
IIdType tid1;
{
Task task = new Task();
task.getRequester().setOnBehalfOf(new Reference(oid1));
tid1 = myTaskDao.create(task, mySrd).getId().toUnqualifiedVersionless();
}
IIdType tid2;
{
Task task = new Task();
task.setOwner(new Reference(oid1));
tid2 = myTaskDao.create(task, mySrd).getId().toUnqualifiedVersionless();
}
SearchParameterMap map;
List<IIdType> ids;
map = new SearchParameterMap();
map.add(Task.SP_ORGANIZATION, new ReferenceParam(oid1.getValue()));
ids = toUnqualifiedVersionlessIds(myTaskDao.search(map));
assertThat(ids, contains(tid1)); // NOT tid2
}
@SuppressWarnings("unused")
@Test
public void testSearchResourceReferenceMissingChain() {
IIdType oid1;
{
Organization org = new Organization();
org.setActive(true);
oid1 = myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless();
}
IIdType tid1;
{
Task task = new Task();
task.getRequester().setOnBehalfOf(new Reference(oid1));
tid1 = myTaskDao.create(task, mySrd).getId().toUnqualifiedVersionless();
}
IIdType tid2;
{
Task task = new Task();
task.setOwner(new Reference(oid1));
tid2 = myTaskDao.create(task, mySrd).getId().toUnqualifiedVersionless();
}
IIdType oid2;
{
Organization org = new Organization();
org.setActive(true);
org.setName("NAME");
oid2 = myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless();
}
IIdType tid3;
{
Task task = new Task();
task.getRequester().setOnBehalfOf(new Reference(oid2));
tid3 = myTaskDao.create(task, mySrd).getId().toUnqualifiedVersionless();
}
SearchParameterMap map;
List<IIdType> ids;
map = new SearchParameterMap();
map.add(Organization.SP_NAME, new StringParam().setMissing(true));
ids = toUnqualifiedVersionlessIds(myOrganizationDao.search(map));
assertThat(ids, contains(oid1));
ourLog.info("Starting Search 2");
map = new SearchParameterMap();
map.add(Task.SP_ORGANIZATION, new ReferenceParam("Organization", "name:missing", "true"));
ids = toUnqualifiedVersionlessIds(myTaskDao.search(map));
assertThat(ids, contains(tid1)); // NOT tid2
map = new SearchParameterMap();
map.add(Task.SP_ORGANIZATION, new ReferenceParam("Organization", "name:missing", "false"));
ids = toUnqualifiedVersionlessIds(myTaskDao.search(map));
assertThat(ids, contains(tid3));
map = new SearchParameterMap();
map.add(Task.SP_ORGANIZATION, new ReferenceParam("Organization", "name:missing", "true"));
ids = toUnqualifiedVersionlessIds(myPatientDao.search(map));
assertThat(ids, empty());
}
/** /**
* See #441 * See #441
*/ */