Avoid multi-term for ElasticSearch (#1717)
* Avoid multi-term for ElasticSearch * Add changelog * Remove redundant code
This commit is contained in:
parent
fba28950ec
commit
ab8dfa5a03
|
@ -0,0 +1,6 @@
|
||||||
|
---
|
||||||
|
type: fix
|
||||||
|
issue: 1717
|
||||||
|
title: ValueSet expansions containing lists of terms did not correctly expand when backed by
|
||||||
|
ElasticSearch due to the use of a feature not supported in ES. Thanks to Jens Villadsen for
|
||||||
|
reporting!
|
|
@ -66,6 +66,7 @@ import org.apache.lucene.search.BooleanQuery;
|
||||||
import org.apache.lucene.search.MultiPhraseQuery;
|
import org.apache.lucene.search.MultiPhraseQuery;
|
||||||
import org.apache.lucene.search.Query;
|
import org.apache.lucene.search.Query;
|
||||||
import org.apache.lucene.search.RegexpQuery;
|
import org.apache.lucene.search.RegexpQuery;
|
||||||
|
import org.apache.lucene.search.TermQuery;
|
||||||
import org.hibernate.ScrollMode;
|
import org.hibernate.ScrollMode;
|
||||||
import org.hibernate.ScrollableResults;
|
import org.hibernate.ScrollableResults;
|
||||||
import org.hibernate.search.jpa.FullTextEntityManager;
|
import org.hibernate.search.jpa.FullTextEntityManager;
|
||||||
|
@ -600,11 +601,16 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc, ApplicationCo
|
||||||
.map(t -> new Term("myCode", t))
|
.map(t -> new Term("myCode", t))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
if (codes.size() > 0) {
|
if (codes.size() > 0) {
|
||||||
MultiPhraseQuery query = new MultiPhraseQuery();
|
|
||||||
query.add(codes.toArray(new Term[0]));
|
BooleanQuery.Builder builder = new BooleanQuery.Builder();
|
||||||
|
builder.setMinimumNumberShouldMatch(1);
|
||||||
|
for (Term nextCode : codes) {
|
||||||
|
builder.add(new TermQuery(nextCode), BooleanClause.Occur.SHOULD);
|
||||||
|
}
|
||||||
|
|
||||||
luceneQuery = new BooleanQuery.Builder()
|
luceneQuery = new BooleanQuery.Builder()
|
||||||
.add(luceneQuery, BooleanClause.Occur.MUST)
|
.add(luceneQuery, BooleanClause.Occur.MUST)
|
||||||
.add(query, BooleanClause.Occur.MUST)
|
.add(builder.build(), BooleanClause.Occur.MUST)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ import ca.uhn.fhir.rest.param.StringParam;
|
||||||
import ca.uhn.fhir.util.TestUtil;
|
import ca.uhn.fhir.util.TestUtil;
|
||||||
import ca.uhn.fhir.validation.FhirValidator;
|
import ca.uhn.fhir.validation.FhirValidator;
|
||||||
import ca.uhn.fhir.validation.ValidationResult;
|
import ca.uhn.fhir.validation.ValidationResult;
|
||||||
|
import org.hamcrest.Matchers;
|
||||||
import org.hl7.fhir.instance.model.api.IIdType;
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
import org.hl7.fhir.r4.model.*;
|
import org.hl7.fhir.r4.model.*;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
|
@ -37,8 +38,10 @@ import org.springframework.test.context.ContextConfiguration;
|
||||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
import org.springframework.transaction.PlatformTransactionManager;
|
import org.springframework.transaction.PlatformTransactionManager;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
@ -146,6 +149,53 @@ public class FhirResourceDaoR4SearchWithElasticSearchTest extends BaseJpaTest {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testExpandVsWithMultiInclude_All() throws IOException {
|
||||||
|
CodeSystem cs = loadResource(myFhirCtx, CodeSystem.class, "/r4/expand-multi-cs.json");
|
||||||
|
myCodeSystemDao.update(cs);
|
||||||
|
|
||||||
|
ValueSet vs = loadResource(myFhirCtx, ValueSet.class, "/r4/expand-multi-vs-all.json");
|
||||||
|
ValueSet expanded = myValueSetDao.expand(vs, null);
|
||||||
|
|
||||||
|
ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(expanded));
|
||||||
|
|
||||||
|
// All codes
|
||||||
|
List<String> codes = expanded
|
||||||
|
.getExpansion()
|
||||||
|
.getContains()
|
||||||
|
.stream()
|
||||||
|
.map(t -> t.getCode())
|
||||||
|
.sorted()
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
assertThat(codes.toString(), codes, Matchers.contains("advice", "message", "note", "notification"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testExpandVsWithMultiInclude_Some() throws IOException {
|
||||||
|
CodeSystem cs = loadResource(myFhirCtx, CodeSystem.class, "/r4/expand-multi-cs.json");
|
||||||
|
myCodeSystemDao.update(cs);
|
||||||
|
|
||||||
|
ValueSet vs = loadResource(myFhirCtx, ValueSet.class, "/r4/expand-multi-vs-all.json");
|
||||||
|
vs.getCompose().getInclude().get(0).getConcept().remove(0);
|
||||||
|
vs.getCompose().getInclude().get(0).getConcept().remove(0);
|
||||||
|
|
||||||
|
ValueSet expanded = myValueSetDao.expand(vs, null);
|
||||||
|
|
||||||
|
ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(expanded));
|
||||||
|
|
||||||
|
// All codes
|
||||||
|
List<String> codes = expanded
|
||||||
|
.getExpansion()
|
||||||
|
.getContains()
|
||||||
|
.stream()
|
||||||
|
.map(t -> t.getCode())
|
||||||
|
.sorted()
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
assertThat(codes.toString(), codes, Matchers.contains("advice", "note"));
|
||||||
|
}
|
||||||
|
|
||||||
private CodeSystem createExternalCs() {
|
private CodeSystem createExternalCs() {
|
||||||
CodeSystem codeSystem = new CodeSystem();
|
CodeSystem codeSystem = new CodeSystem();
|
||||||
codeSystem.setUrl(URL_MY_CODE_SYSTEM);
|
codeSystem.setUrl(URL_MY_CODE_SYSTEM);
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
{
|
||||||
|
"resourceType" : "CodeSystem",
|
||||||
|
"id" : "ehealth-message-category",
|
||||||
|
"text" : {
|
||||||
|
"status" : "generated",
|
||||||
|
"div" : "<div xmlns=\"http://www.w3.org/1999/xhtml\"><h2>MessageCategory</h2><div><p>Message category types</p>\n</div><p>This code system http://ehealth.sundhed.dk/cs/message-category defines the following codes:</p><table class=\"codes\"><tr><td style=\"white-space:nowrap\"><b>Code</b></td><td><b>Display</b></td><td><b>Definition</b></td></tr><tr><td style=\"white-space:nowrap\">message<a name=\"ehealth-message-category-message\"> </a></td><td>Message</td><td/></tr><tr><td style=\"white-space:nowrap\">notification<a name=\"ehealth-message-category-notification\"> </a></td><td>Notification</td><td/></tr><tr><td style=\"white-space:nowrap\">advice<a name=\"ehealth-message-category-advice\"> </a></td><td>Advice</td><td/></tr><tr><td style=\"white-space:nowrap\">note<a name=\"ehealth-message-category-note\"> </a></td><td>Note</td><td/></tr></table></div>"
|
||||||
|
},
|
||||||
|
"url" : "http://ehealth.sundhed.dk/cs/message-category",
|
||||||
|
"version" : "0.6.0",
|
||||||
|
"name" : "MessageCategory",
|
||||||
|
"status" : "active",
|
||||||
|
"experimental" : false,
|
||||||
|
"date" : "2019-01-29T00:00:00+00:00",
|
||||||
|
"publisher" : "ehealth.sundhed.dk",
|
||||||
|
"contact" : [
|
||||||
|
{
|
||||||
|
"telecom" : [
|
||||||
|
{
|
||||||
|
"system" : "url",
|
||||||
|
"value" : "http://ehealth.sundhed.dk/terminology"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description" : "Message category types",
|
||||||
|
"caseSensitive" : true,
|
||||||
|
"content" : "complete",
|
||||||
|
"concept" : [
|
||||||
|
{
|
||||||
|
"code" : "message",
|
||||||
|
"display" : "Message",
|
||||||
|
"designation" : [
|
||||||
|
{
|
||||||
|
"language" : "en-US",
|
||||||
|
"value" : "Message"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"language" : "da",
|
||||||
|
"value" : "Besked"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code" : "notification",
|
||||||
|
"display" : "Notification",
|
||||||
|
"designation" : [
|
||||||
|
{
|
||||||
|
"language" : "en-US",
|
||||||
|
"value" : "Notification"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"language" : "da",
|
||||||
|
"value" : "Notifikation"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code" : "advice",
|
||||||
|
"display" : "Advice",
|
||||||
|
"designation" : [
|
||||||
|
{
|
||||||
|
"language" : "en-US",
|
||||||
|
"value" : "Advice"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"language" : "da",
|
||||||
|
"value" : "Advisering"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code" : "note",
|
||||||
|
"display" : "Note",
|
||||||
|
"designation" : [
|
||||||
|
{
|
||||||
|
"language" : "en-US",
|
||||||
|
"value" : "Note"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"language" : "da",
|
||||||
|
"value" : "Note"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,92 @@
|
||||||
|
{
|
||||||
|
"resourceType" : "ValueSet",
|
||||||
|
"id" : "message-category",
|
||||||
|
"text" : {
|
||||||
|
"status" : "generated",
|
||||||
|
"div" : "<div xmlns=\"http://www.w3.org/1999/xhtml\"><h2>MessageCategory</h2><div><p>The set of possible message types</p>\n</div><p>This value set includes codes from the following code systems:</p><ul><li>Include these codes as defined in <a href=\"CodeSystem-ehealth-message-category.html\"><code>http://ehealth.sundhed.dk/cs/message-category</code></a><table class=\"none\"><tr><td style=\"white-space:nowrap\"><b>Code</b></td><td><b>Display</b></td></tr><tr><td><a href=\"CodeSystem-ehealth-message-category.html#ehealth-message-category-message\">message</a></td><td>Message</td><td/></tr><tr><td><a href=\"CodeSystem-ehealth-message-category.html#ehealth-message-category-notification\">notification</a></td><td>Notification</td><td/></tr><tr><td><a href=\"CodeSystem-ehealth-message-category.html#ehealth-message-category-advice\">advice</a></td><td>Advice</td><td/></tr><tr><td><a href=\"CodeSystem-ehealth-message-category.html#ehealth-message-category-note\">note</a></td><td>Note</td><td/></tr></table></li></ul><p><b>Additional Language Displays</b></p><table class=\"codes\"><tr><td><b>Code</b></td><td><b>Dansk (Danish, da)</b></td><td><b>English (United States) (English (United States), en)</b></td></tr><tr><td>message</td><td>Besked</td><td>Message</td></tr><tr><td>notification</td><td>Notifikation</td><td>Notification</td></tr><tr><td>advice</td><td>Advisering</td><td>Advice</td></tr><tr><td>note</td><td>Note</td><td>Note</td></tr></table></div>"
|
||||||
|
},
|
||||||
|
"url" : "http://ehealth.sundhed.dk/vs/message-category",
|
||||||
|
"version" : "0.0.1",
|
||||||
|
"name" : "MessageCategory",
|
||||||
|
"status" : "active",
|
||||||
|
"experimental" : true,
|
||||||
|
"date" : "2019-02-08T00:00:00+00:00",
|
||||||
|
"publisher" : "ehealth.sundhed.dk",
|
||||||
|
"contact" : [
|
||||||
|
{
|
||||||
|
"name" : "FUT",
|
||||||
|
"telecom" : [
|
||||||
|
{
|
||||||
|
"system" : "url",
|
||||||
|
"value" : "https://digst.dk/digital-service/digital-velfaerd/telemedicin-kol/faelles-udbud-af-telemedicin-fut/"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description" : "The set of possible message types",
|
||||||
|
"compose" : {
|
||||||
|
"include" : [
|
||||||
|
{
|
||||||
|
"system" : "http://ehealth.sundhed.dk/cs/message-category",
|
||||||
|
"concept" : [
|
||||||
|
{
|
||||||
|
"code" : "message",
|
||||||
|
"display" : "Message",
|
||||||
|
"designation" : [
|
||||||
|
{
|
||||||
|
"language" : "en-US",
|
||||||
|
"value" : "Message"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"language" : "da",
|
||||||
|
"value" : "Besked"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code" : "notification",
|
||||||
|
"display" : "Notification",
|
||||||
|
"designation" : [
|
||||||
|
{
|
||||||
|
"language" : "en-US",
|
||||||
|
"value" : "Notification"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"language" : "da",
|
||||||
|
"value" : "Notifikation"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code" : "advice",
|
||||||
|
"display" : "Advice",
|
||||||
|
"designation" : [
|
||||||
|
{
|
||||||
|
"language" : "en-US",
|
||||||
|
"value" : "Advice"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"language" : "da",
|
||||||
|
"value" : "Advisering"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code" : "note",
|
||||||
|
"display" : "Note",
|
||||||
|
"designation" : [
|
||||||
|
{
|
||||||
|
"language" : "en-US",
|
||||||
|
"value" : "Note"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"language" : "da",
|
||||||
|
"value" : "Note"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue