Changed observation indexing to bypass hibernate search and removed Observation index tables.
This commit is contained in:
parent
6e507bf642
commit
9696af5dc0
|
@ -21,36 +21,26 @@ package ca.uhn.fhir.jpa.dao;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import ca.uhn.fhir.context.*;
|
import ca.uhn.fhir.context.*;
|
||||||
import ca.uhn.fhir.jpa.dao.data.IObservationIndexedCodeCodingSearchParamDao;
|
|
||||||
import ca.uhn.fhir.jpa.dao.data.IObservationIndexedSearchParamLastNDao;
|
|
||||||
import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
|
import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
|
||||||
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamToken;
|
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamToken;
|
||||||
|
import ca.uhn.fhir.jpa.model.util.CodeSystemHash;
|
||||||
|
import ca.uhn.fhir.jpa.search.lastn.IElasticsearchSvc;
|
||||||
|
import ca.uhn.fhir.jpa.search.lastn.json.CodeJson;
|
||||||
|
import ca.uhn.fhir.jpa.search.lastn.json.ObservationJson;
|
||||||
import ca.uhn.fhir.jpa.searchparam.extractor.ISearchParamExtractor;
|
import ca.uhn.fhir.jpa.searchparam.extractor.ISearchParamExtractor;
|
||||||
import ca.uhn.fhir.jpa.searchparam.extractor.PathAndRef;
|
import ca.uhn.fhir.jpa.searchparam.extractor.PathAndRef;
|
||||||
import org.hl7.fhir.instance.model.api.*;
|
import org.hl7.fhir.instance.model.api.*;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.transaction.annotation.Propagation;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
|
|
||||||
import javax.persistence.EntityManager;
|
|
||||||
import javax.persistence.PersistenceContext;
|
|
||||||
import javax.persistence.PersistenceContextType;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@Transactional(propagation = Propagation.REQUIRED)
|
|
||||||
public class ObservationLastNIndexPersistSvc {
|
public class ObservationLastNIndexPersistSvc {
|
||||||
|
|
||||||
@PersistenceContext(type = PersistenceContextType.TRANSACTION)
|
|
||||||
protected EntityManager myEntityManager;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
IObservationIndexedSearchParamLastNDao myResourceIndexedObservationLastNDao;
|
private ISearchParamExtractor mySearchParameterExtractor;
|
||||||
|
|
||||||
@Autowired
|
@Autowired(required = false)
|
||||||
IObservationIndexedCodeCodingSearchParamDao myObservationIndexedCodeCodingSearchParamDao;
|
private IElasticsearchSvc myElasticsearchSvc;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public ISearchParamExtractor mySearchParameterExtractor;
|
|
||||||
|
|
||||||
public void indexObservation(IBaseResource theResource) {
|
public void indexObservation(IBaseResource theResource) {
|
||||||
|
|
||||||
|
@ -95,15 +85,12 @@ public class ObservationLastNIndexPersistSvc {
|
||||||
List<IBase> theObservationCategoryCodeableConcepts) {
|
List<IBase> theObservationCategoryCodeableConcepts) {
|
||||||
|
|
||||||
// Determine if an index already exists for Observation:
|
// Determine if an index already exists for Observation:
|
||||||
boolean observationIndexUpdate = false;
|
ObservationJson indexedObservation = null;
|
||||||
ObservationIndexedSearchParamLastNEntity indexedObservation = null;
|
|
||||||
if (resourcePID != null) {
|
if (resourcePID != null) {
|
||||||
indexedObservation = myResourceIndexedObservationLastNDao.findByIdentifier(resourcePID);
|
indexedObservation = myElasticsearchSvc.getObservationDocument(resourcePID);
|
||||||
}
|
}
|
||||||
if (indexedObservation == null) {
|
if (indexedObservation == null) {
|
||||||
indexedObservation = new ObservationIndexedSearchParamLastNEntity();
|
indexedObservation = new ObservationJson();
|
||||||
} else {
|
|
||||||
observationIndexUpdate = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
indexedObservation.setEffectiveDtm(theEffectiveDtm);
|
indexedObservation.setEffectiveDtm(theEffectiveDtm);
|
||||||
|
@ -114,77 +101,65 @@ public class ObservationLastNIndexPersistSvc {
|
||||||
|
|
||||||
addCategoriesToObservationIndex(theObservationCategoryCodeableConcepts, indexedObservation);
|
addCategoriesToObservationIndex(theObservationCategoryCodeableConcepts, indexedObservation);
|
||||||
|
|
||||||
if (observationIndexUpdate) {
|
myElasticsearchSvc.createOrUpdateObservationIndex(resourcePID, indexedObservation);
|
||||||
myEntityManager.merge(indexedObservation);
|
|
||||||
} else {
|
|
||||||
myEntityManager.persist(indexedObservation);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addCodeToObservationIndex(List<IBase> theObservationCodeCodeableConcepts,
|
private void addCodeToObservationIndex(List<IBase> theObservationCodeCodeableConcepts,
|
||||||
ObservationIndexedSearchParamLastNEntity theIndexedObservation) {
|
ObservationJson theIndexedObservation) {
|
||||||
// Determine if a Normalized ID was created previously for Observation Code
|
// Determine if a Normalized ID was created previously for Observation Code
|
||||||
Optional<String> existingObservationCodeNormalizedId = getCodeCodeableConceptIdIfExists(theObservationCodeCodeableConcepts.get(0));
|
String existingObservationCodeNormalizedId = getCodeCodeableConceptId(theObservationCodeCodeableConcepts.get(0));
|
||||||
|
|
||||||
// Create/update normalized Observation Code index record
|
// Create/update normalized Observation Code index record
|
||||||
ObservationIndexedCodeCodeableConceptEntity codeableConceptField =
|
CodeJson codeableConceptField =
|
||||||
getCodeCodeableConcept(theObservationCodeCodeableConcepts.get(0),
|
getCodeCodeableConcept(theObservationCodeCodeableConcepts.get(0),
|
||||||
existingObservationCodeNormalizedId.orElse(UUID.randomUUID().toString()));
|
existingObservationCodeNormalizedId);
|
||||||
|
|
||||||
if (existingObservationCodeNormalizedId.isPresent()) {
|
myElasticsearchSvc.createOrUpdateObservationCodeIndex(codeableConceptField.getCodeableConceptId(), codeableConceptField);
|
||||||
myEntityManager.merge(codeableConceptField);
|
|
||||||
} else {
|
|
||||||
myEntityManager.persist(codeableConceptField);
|
|
||||||
}
|
|
||||||
|
|
||||||
theIndexedObservation.setObservationCode(codeableConceptField);
|
|
||||||
theIndexedObservation.setCodeNormalizedId(codeableConceptField.getCodeableConceptId());
|
|
||||||
|
|
||||||
|
theIndexedObservation.setCode(codeableConceptField);
|
||||||
|
theIndexedObservation.setCode_concept_id(codeableConceptField.getCodeableConceptId());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addCategoriesToObservationIndex(List<IBase> observationCategoryCodeableConcepts,
|
private void addCategoriesToObservationIndex(List<IBase> observationCategoryCodeableConcepts,
|
||||||
ObservationIndexedSearchParamLastNEntity indexedObservation) {
|
ObservationJson indexedObservation) {
|
||||||
// Build CodeableConcept entities for Observation.Category
|
// Build CodeableConcept entities for Observation.Category
|
||||||
Set<ObservationIndexedCategoryCodeableConceptEntity> categoryCodeableConceptEntities = new HashSet<>();
|
List<CodeJson> categoryCodeableConceptEntities = new ArrayList<>();
|
||||||
for (IBase categoryCodeableConcept : observationCategoryCodeableConcepts) {
|
for (IBase categoryCodeableConcept : observationCategoryCodeableConcepts) {
|
||||||
// Build CodeableConcept entities for each category CodeableConcept
|
// Build CodeableConcept entities for each category CodeableConcept
|
||||||
categoryCodeableConceptEntities.add(getCategoryCodeableConceptEntities(categoryCodeableConcept));
|
categoryCodeableConceptEntities.add(getCategoryCodeableConceptEntities(categoryCodeableConcept));
|
||||||
}
|
}
|
||||||
indexedObservation.setCategoryCodeableConcepts(categoryCodeableConceptEntities);
|
indexedObservation.setCategories(categoryCodeableConceptEntities);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ObservationIndexedCategoryCodeableConceptEntity getCategoryCodeableConceptEntities(IBase theValue) {
|
private CodeJson getCategoryCodeableConceptEntities(IBase theValue) {
|
||||||
String text = mySearchParameterExtractor.getDisplayTextFromCodeableConcept(theValue);
|
String text = mySearchParameterExtractor.getDisplayTextFromCodeableConcept(theValue);
|
||||||
ObservationIndexedCategoryCodeableConceptEntity categoryCodeableConcept = new ObservationIndexedCategoryCodeableConceptEntity(text);
|
CodeJson categoryCodeableConcept = new CodeJson();
|
||||||
|
categoryCodeableConcept.setCodeableConceptText(text);
|
||||||
|
|
||||||
List<IBase> codings = mySearchParameterExtractor.getCodingsFromCodeableConcept(theValue);
|
List<IBase> codings = mySearchParameterExtractor.getCodingsFromCodeableConcept(theValue);
|
||||||
Set<ObservationIndexedCategoryCodingEntity> categoryCodingEntities = new HashSet<>();
|
|
||||||
for (IBase nextCoding : codings) {
|
for (IBase nextCoding : codings) {
|
||||||
categoryCodingEntities.add(getCategoryCoding(nextCoding));
|
addCategoryCoding(nextCoding, categoryCodeableConcept);
|
||||||
}
|
}
|
||||||
|
|
||||||
categoryCodeableConcept.setObservationIndexedCategoryCodingEntitySet(categoryCodingEntities);
|
|
||||||
|
|
||||||
return categoryCodeableConcept;
|
return categoryCodeableConcept;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ObservationIndexedCodeCodeableConceptEntity getCodeCodeableConcept(IBase theValue, String observationCodeNormalizedId) {
|
private CodeJson getCodeCodeableConcept(IBase theValue, String observationCodeNormalizedId) {
|
||||||
String text = mySearchParameterExtractor.getDisplayTextFromCodeableConcept(theValue);
|
String text = mySearchParameterExtractor.getDisplayTextFromCodeableConcept(theValue);
|
||||||
ObservationIndexedCodeCodeableConceptEntity codeCodeableConcept = new ObservationIndexedCodeCodeableConceptEntity(text, observationCodeNormalizedId);
|
CodeJson codeCodeableConcept = new CodeJson();
|
||||||
|
codeCodeableConcept.setCodeableConceptText(text);
|
||||||
|
codeCodeableConcept.setCodeableConceptId(observationCodeNormalizedId);
|
||||||
|
|
||||||
List<IBase> codings = mySearchParameterExtractor.getCodingsFromCodeableConcept(theValue);
|
List<IBase> codings = mySearchParameterExtractor.getCodingsFromCodeableConcept(theValue);
|
||||||
for (IBase nextCoding : codings) {
|
for (IBase nextCoding : codings) {
|
||||||
codeCodeableConcept.addCoding(getCodeCoding(nextCoding, observationCodeNormalizedId));
|
addCodeCoding(nextCoding, codeCodeableConcept);
|
||||||
}
|
}
|
||||||
|
|
||||||
return codeCodeableConcept;
|
return codeCodeableConcept;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Optional<String> getCodeCodeableConceptIdIfExists(IBase theValue) {
|
private String getCodeCodeableConceptId(IBase theValue) {
|
||||||
List<IBase> codings = mySearchParameterExtractor.getCodingsFromCodeableConcept(theValue);
|
List<IBase> codings = mySearchParameterExtractor.getCodingsFromCodeableConcept(theValue);
|
||||||
String codeCodeableConceptId = null;
|
|
||||||
Optional<String> codeCodeableConceptIdOptional = Optional.empty();
|
Optional<String> codeCodeableConceptIdOptional = Optional.empty();
|
||||||
|
|
||||||
for (IBase nextCoding : codings) {
|
for (IBase nextCoding : codings) {
|
||||||
|
@ -196,52 +171,52 @@ public class ObservationLastNIndexPersistSvc {
|
||||||
String system = param.getSystem();
|
String system = param.getSystem();
|
||||||
String code = param.getValue();
|
String code = param.getValue();
|
||||||
String text = mySearchParameterExtractor.getDisplayTextForCoding(nextCoding);
|
String text = mySearchParameterExtractor.getDisplayTextForCoding(nextCoding);
|
||||||
if (code != null && system != null) {
|
|
||||||
codeCodeableConceptIdOptional = Optional.ofNullable(myObservationIndexedCodeCodingSearchParamDao.findByCodeAndSystem(code, system));
|
String codeSystemHash = String.valueOf(CodeSystemHash.hashCodeSystem(system, code));
|
||||||
} else {
|
CodeJson codeCodeableConceptDocument = myElasticsearchSvc.getObservationCodeDocument(codeSystemHash, text);
|
||||||
codeCodeableConceptIdOptional = Optional.ofNullable(myObservationIndexedCodeCodingSearchParamDao.findByDisplay(text));
|
if (codeCodeableConceptDocument != null) {
|
||||||
}
|
codeCodeableConceptIdOptional = Optional.of(codeCodeableConceptDocument.getCodeableConceptId());
|
||||||
if (codeCodeableConceptIdOptional.isPresent()) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return codeCodeableConceptIdOptional;
|
return codeCodeableConceptIdOptional.orElse(UUID.randomUUID().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
private ObservationIndexedCategoryCodingEntity getCategoryCoding(IBase theValue) {
|
private void addCategoryCoding(IBase theValue, CodeJson theCategoryCodeableConcept) {
|
||||||
ResourceIndexedSearchParamToken param = mySearchParameterExtractor.createSearchParamForCoding("Observation",
|
ResourceIndexedSearchParamToken param = mySearchParameterExtractor.createSearchParamForCoding("Observation",
|
||||||
new RuntimeSearchParam(null, null, "category", null, null, null, null, null, null, null),
|
new RuntimeSearchParam(null, null, "category", null, null, null, null, null, null, null),
|
||||||
theValue);
|
theValue);
|
||||||
ObservationIndexedCategoryCodingEntity observationIndexedCategoryCodingEntity = null;
|
|
||||||
if (param != null) {
|
if (param != null) {
|
||||||
String system = param.getSystem();
|
String system = param.getSystem();
|
||||||
String code = param.getValue();
|
String code = param.getValue();
|
||||||
String text = mySearchParameterExtractor.getDisplayTextForCoding(theValue);
|
String text = mySearchParameterExtractor.getDisplayTextForCoding(theValue);
|
||||||
observationIndexedCategoryCodingEntity = new ObservationIndexedCategoryCodingEntity(system, code, text);
|
theCategoryCodeableConcept.addCoding(system, code, text);
|
||||||
}
|
}
|
||||||
return observationIndexedCategoryCodingEntity;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ObservationIndexedCodeCodingEntity getCodeCoding(IBase theValue, String observationCodeNormalizedId) {
|
private void addCodeCoding(IBase theValue, CodeJson theObservationCode) {
|
||||||
ResourceIndexedSearchParamToken param = mySearchParameterExtractor.createSearchParamForCoding("Observation",
|
ResourceIndexedSearchParamToken param = mySearchParameterExtractor.createSearchParamForCoding("Observation",
|
||||||
new RuntimeSearchParam(null, null, "code", null, null, null, null, null, null, null),
|
new RuntimeSearchParam(null, null, "code", null, null, null, null, null, null, null),
|
||||||
theValue);
|
theValue);
|
||||||
ObservationIndexedCodeCodingEntity observationIndexedCodeCodingEntity = null;
|
|
||||||
if (param != null) {
|
if (param != null) {
|
||||||
String system = param.getSystem();
|
String system = param.getSystem();
|
||||||
String code = param.getValue();
|
String code = param.getValue();
|
||||||
String text = mySearchParameterExtractor.getDisplayTextForCoding(theValue);
|
String text = mySearchParameterExtractor.getDisplayTextForCoding(theValue);
|
||||||
observationIndexedCodeCodingEntity = new ObservationIndexedCodeCodingEntity(system, code, text, observationCodeNormalizedId);
|
theObservationCode.addCoding(system, code, text);
|
||||||
}
|
}
|
||||||
return observationIndexedCodeCodingEntity;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deleteObservationIndex(IBasePersistedResource theEntity) {
|
public void deleteObservationIndex(IBasePersistedResource theEntity) {
|
||||||
ObservationIndexedSearchParamLastNEntity deletedObservationLastNEntity = myResourceIndexedObservationLastNDao.findByIdentifier(theEntity.getIdDt().getIdPart());
|
if (myElasticsearchSvc == null) {
|
||||||
|
// Elasticsearch is not enabled and therefore no index needs to be updated.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ObservationJson deletedObservationLastNEntity = myElasticsearchSvc.getObservationDocument(theEntity.getIdDt().getIdPart());
|
||||||
if (deletedObservationLastNEntity != null) {
|
if (deletedObservationLastNEntity != null) {
|
||||||
myEntityManager.remove(deletedObservationLastNEntity);
|
myElasticsearchSvc.deleteObservationDocument(deletedObservationLastNEntity.getIdentifier());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,46 +0,0 @@
|
||||||
package ca.uhn.fhir.jpa.dao.data;
|
|
||||||
|
|
||||||
/*-
|
|
||||||
* #%L
|
|
||||||
* HAPI FHIR JPA Server
|
|
||||||
* %%
|
|
||||||
* Copyright (C) 2014 - 2020 University Health Network
|
|
||||||
* %%
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
|
|
||||||
import ca.uhn.fhir.jpa.model.entity.ObservationIndexedCodeCodingEntity;
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
|
||||||
import org.springframework.data.jpa.repository.Query;
|
|
||||||
import org.springframework.data.repository.query.Param;
|
|
||||||
import org.springframework.stereotype.Repository;
|
|
||||||
|
|
||||||
@Repository
|
|
||||||
public interface IObservationIndexedCodeCodingSearchParamDao extends JpaRepository<ObservationIndexedCodeCodingEntity, Long> {
|
|
||||||
|
|
||||||
@Query("" +
|
|
||||||
"SELECT t.myCodeableConceptId FROM ObservationIndexedCodeCodingEntity t " +
|
|
||||||
"WHERE t.myCode = :code " +
|
|
||||||
"AND t.mySystem = :system " +
|
|
||||||
"")
|
|
||||||
String findByCodeAndSystem(@Param("code") String theCode, @Param("system") String theSystem);
|
|
||||||
|
|
||||||
|
|
||||||
@Query("" +
|
|
||||||
"SELECT t.myCodeableConceptId FROM ObservationIndexedCodeCodingEntity t " +
|
|
||||||
"WHERE t.myDisplay = :display" +
|
|
||||||
"")
|
|
||||||
String findByDisplay(@Param("display") String theDisplay);
|
|
||||||
|
|
||||||
}
|
|
|
@ -229,7 +229,7 @@ public class ElasticsearchSvcImpl implements IElasticsearchSvc {
|
||||||
|
|
||||||
private CompositeAggregationBuilder createObservationSubjectAggregationBuilder(int theMaxNumberObservationsPerCode, String[] theTopHitsInclude) {
|
private CompositeAggregationBuilder createObservationSubjectAggregationBuilder(int theMaxNumberObservationsPerCode, String[] theTopHitsInclude) {
|
||||||
CompositeValuesSourceBuilder<?> subjectValuesBuilder = new TermsValuesSourceBuilder("subject").field("subject");
|
CompositeValuesSourceBuilder<?> subjectValuesBuilder = new TermsValuesSourceBuilder("subject").field("subject");
|
||||||
List<CompositeValuesSourceBuilder<?>> compositeAggSubjectSources = new ArrayList();
|
List<CompositeValuesSourceBuilder<?>> compositeAggSubjectSources = new ArrayList<>();
|
||||||
compositeAggSubjectSources.add(subjectValuesBuilder);
|
compositeAggSubjectSources.add(subjectValuesBuilder);
|
||||||
CompositeAggregationBuilder compositeAggregationSubjectBuilder = new CompositeAggregationBuilder(GROUP_BY_SUBJECT, compositeAggSubjectSources);
|
CompositeAggregationBuilder compositeAggregationSubjectBuilder = new CompositeAggregationBuilder(GROUP_BY_SUBJECT, compositeAggSubjectSources);
|
||||||
compositeAggregationSubjectBuilder.subAggregation(createObservationCodeAggregationBuilder(theMaxNumberObservationsPerCode, theTopHitsInclude));
|
compositeAggregationSubjectBuilder.subAggregation(createObservationCodeAggregationBuilder(theMaxNumberObservationsPerCode, theTopHitsInclude));
|
||||||
|
@ -514,12 +514,12 @@ public class ElasticsearchSvcImpl implements IElasticsearchSvc {
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
List<ObservationJson> executeLastNWithAllFields(SearchParameterMap theSearchParameterMap, FhirContext theFhirContext) {
|
public List<ObservationJson> executeLastNWithAllFieldsForTest(SearchParameterMap theSearchParameterMap, FhirContext theFhirContext) {
|
||||||
return buildAndExecuteSearch(theSearchParameterMap, theFhirContext, null, t -> t, 100);
|
return buildAndExecuteSearch(theSearchParameterMap, theFhirContext, null, t -> t, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
List<CodeJson> queryAllIndexedObservationCodes() throws IOException {
|
List<CodeJson> queryAllIndexedObservationCodesForTest() throws IOException {
|
||||||
SearchRequest codeSearchRequest = new SearchRequest(OBSERVATION_CODE_INDEX);
|
SearchRequest codeSearchRequest = new SearchRequest(OBSERVATION_CODE_INDEX);
|
||||||
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
|
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
|
||||||
// Query
|
// Query
|
||||||
|
|
|
@ -21,6 +21,8 @@ package ca.uhn.fhir.jpa.search.lastn;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
import ca.uhn.fhir.jpa.search.lastn.json.CodeJson;
|
||||||
|
import ca.uhn.fhir.jpa.search.lastn.json.ObservationJson;
|
||||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -35,4 +37,42 @@ public interface IElasticsearchSvc {
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
List<String> executeLastN(SearchParameterMap theSearchParameterMap, FhirContext theFhirContext, Integer theMaxResultsToFetch);
|
List<String> executeLastN(SearchParameterMap theSearchParameterMap, FhirContext theFhirContext, Integer theMaxResultsToFetch);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns index document for a single Observation
|
||||||
|
* @param theDocumentID Identifier of Observation resource.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
ObservationJson getObservationDocument(String theDocumentID);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns index document for a single Observation Code that either has a coding that matches a specified Code value and system or that has a specified text value.
|
||||||
|
* @param theCodeSystemHash A hash string constructed from a Code value and Code system used to match to an Observation Code.
|
||||||
|
* @param theText A text value used to match to an Observation Code.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
CodeJson getObservationCodeDocument(String theCodeSystemHash, String theText);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates or updates index for an Observation Resource.
|
||||||
|
* @param theDocumentId Identifier for Observation resource.
|
||||||
|
* @param theObservationDocument Indexing document for Observation.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Boolean createOrUpdateObservationIndex(String theDocumentId, ObservationJson theObservationDocument);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates or updates index for an Observation Code.
|
||||||
|
* @param theCodeableConceptID Identifier for Observation resource.
|
||||||
|
* @param theObservationCodeDocument Indexing document for Observation.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Boolean createOrUpdateObservationCodeIndex(String theCodeableConceptID, CodeJson theObservationCodeDocument);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes index for an Observation Resource.
|
||||||
|
* @param theDocumentId Identifier for Observation resource.
|
||||||
|
*/
|
||||||
|
void deleteObservationDocument(String theDocumentId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,8 +24,6 @@ import ca.uhn.fhir.jpa.model.util.CodeSystemHash;
|
||||||
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
||||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
import org.hl7.fhir.r4.model.CodeableConcept;
|
|
||||||
import org.hl7.fhir.r4.model.Coding;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -55,22 +53,26 @@ public class CodeJson {
|
||||||
public CodeJson(){
|
public CodeJson(){
|
||||||
}
|
}
|
||||||
|
|
||||||
public CodeJson(CodeableConcept theCodeableConcept, String theCodeableConceptId) {
|
public void setCodeableConceptId(String theCodeableConceptId) {
|
||||||
myCodeableConceptText = theCodeableConcept.getText();
|
myCodeableConceptId = theCodeableConceptId;
|
||||||
myCodeableConceptId = theCodeableConceptId;
|
}
|
||||||
for (Coding theCoding : theCodeableConcept.getCoding()) {
|
|
||||||
myCoding_code.add(theCoding.getCode());
|
|
||||||
myCoding_system.add(theCoding.getSystem());
|
|
||||||
myCoding_display.add(theCoding.getDisplay());
|
|
||||||
myCoding_code_system_hash.add(String.valueOf(CodeSystemHash.hashCodeSystem(theCoding.getSystem(), theCoding.getCode())));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCodeableConceptId() {
|
public void addCoding(String theCoding_system, String theCoding_code, String theCoding_display) {
|
||||||
|
myCoding_code.add(theCoding_code);
|
||||||
|
myCoding_system.add(theCoding_system);
|
||||||
|
myCoding_display.add(theCoding_display);
|
||||||
|
myCoding_code_system_hash.add(String.valueOf(CodeSystemHash.hashCodeSystem(theCoding_system, theCoding_code)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCodeableConceptId() {
|
||||||
return myCodeableConceptId;
|
return myCodeableConceptId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getCodeableConceptText() {
|
public void setCodeableConceptText(String theCodeableConceptText) {
|
||||||
|
myCodeableConceptText = theCodeableConceptText;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCodeableConceptText() {
|
||||||
return myCodeableConceptText;
|
return myCodeableConceptText;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,11 +80,11 @@ public class CodeJson {
|
||||||
return myCoding_code;
|
return myCoding_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getCoding_code_system_hash() {
|
public List<String> getCoding_code_system_hash() {
|
||||||
return myCoding_code_system_hash;
|
return myCoding_code_system_hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getCoding_display() {
|
public List<String> getCoding_display() {
|
||||||
return myCoding_display;
|
return myCoding_display;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,8 +24,6 @@ import ca.uhn.fhir.jpa.model.util.CodeSystemHash;
|
||||||
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
||||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
import org.hl7.fhir.r4.model.CodeableConcept;
|
|
||||||
import org.hl7.fhir.r4.model.Coding;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
@ -88,18 +86,24 @@ public class ObservationJson {
|
||||||
mySubject = theSubject;
|
mySubject = theSubject;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCategories(List<CodeableConcept> theCategories) {
|
public void setCategories(List<CodeJson> theCategories) {
|
||||||
for (CodeableConcept theConcept : theCategories) {
|
for (CodeJson theConcept : theCategories) {
|
||||||
myCategory_concept_text.add(theConcept.getText());
|
myCategory_concept_text.add(theConcept.getCodeableConceptText());
|
||||||
List<String> coding_code_system_hashes = new ArrayList<>();
|
List<String> coding_code_system_hashes = new ArrayList<>();
|
||||||
List<String> coding_codes = new ArrayList<>();
|
List<String> coding_codes = new ArrayList<>();
|
||||||
List<String> coding_displays = new ArrayList<>();
|
List<String> coding_displays = new ArrayList<>();
|
||||||
List<String> coding_systems = new ArrayList<>();
|
List<String> coding_systems = new ArrayList<>();
|
||||||
for (Coding theCategoryCoding : theConcept.getCoding()) {
|
for (String theCategoryCoding_code : theConcept.getCoding_code()) {
|
||||||
coding_code_system_hashes.add(String.valueOf(CodeSystemHash.hashCodeSystem(theCategoryCoding.getSystem(), theCategoryCoding.getCode())));
|
coding_codes.add(theCategoryCoding_code);
|
||||||
coding_codes.add(theCategoryCoding.getCode());
|
}
|
||||||
coding_displays.add(theCategoryCoding.getDisplay());
|
for (String theCategoryCoding_system : theConcept.getCoding_system()) {
|
||||||
coding_systems.add(theCategoryCoding.getSystem());
|
coding_systems.add(theCategoryCoding_system);
|
||||||
|
}
|
||||||
|
for (String theCategoryCoding_code_system_hash : theConcept.getCoding_code_system_hash()) {
|
||||||
|
coding_code_system_hashes.add(theCategoryCoding_code_system_hash);
|
||||||
|
}
|
||||||
|
for (String theCategoryCoding_display : theConcept.getCoding_display()) {
|
||||||
|
coding_displays.add(theCategoryCoding_display);
|
||||||
}
|
}
|
||||||
myCategory_coding_code_system_hash.add(coding_code_system_hashes);
|
myCategory_coding_code_system_hash.add(coding_code_system_hashes);
|
||||||
myCategory_coding_code.add(coding_codes);
|
myCategory_coding_code.add(coding_codes);
|
||||||
|
@ -128,14 +132,13 @@ public class ObservationJson {
|
||||||
return myCategory_coding_system;
|
return myCategory_coding_system;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCode(CodeableConcept theCode) {
|
public void setCode(CodeJson theCode) {
|
||||||
myCode_concept_text = theCode.getText();
|
myCode_concept_text = theCode.getCodeableConceptText();
|
||||||
for (Coding theCodeCoding : theCode.getCoding()) {
|
// Currently can only support one Coding for Observation Code
|
||||||
myCode_coding_code_system_hash = String.valueOf(CodeSystemHash.hashCodeSystem(theCodeCoding.getSystem(), theCodeCoding.getCode()));
|
myCode_coding_code_system_hash = theCode.getCoding_code_system_hash().get(0);
|
||||||
myCode_coding_code = theCodeCoding.getCode();
|
myCode_coding_code = theCode.getCoding_code().get(0);
|
||||||
myCode_coding_display = theCodeCoding.getDisplay();
|
myCode_coding_display = theCode.getCoding_display().get(0);
|
||||||
myCode_coding_system = theCodeCoding.getSystem();
|
myCode_coding_system = theCode.getCoding_system().get(0);
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoObservation;
|
||||||
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoPatient;
|
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoPatient;
|
||||||
import ca.uhn.fhir.jpa.config.TestR4ConfigWithElasticsearchClient;
|
import ca.uhn.fhir.jpa.config.TestR4ConfigWithElasticsearchClient;
|
||||||
import ca.uhn.fhir.jpa.dao.BaseJpaTest;
|
import ca.uhn.fhir.jpa.dao.BaseJpaTest;
|
||||||
import ca.uhn.fhir.jpa.dao.SearchBuilder;
|
import ca.uhn.fhir.jpa.search.lastn.ElasticsearchSvcImpl;
|
||||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||||
import ca.uhn.fhir.rest.param.ReferenceAndListParam;
|
import ca.uhn.fhir.rest.param.ReferenceAndListParam;
|
||||||
import ca.uhn.fhir.rest.param.ReferenceOrListParam;
|
import ca.uhn.fhir.rest.param.ReferenceOrListParam;
|
||||||
|
@ -31,6 +31,7 @@ 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.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
@ -61,6 +62,9 @@ public class BaseR4SearchLastN extends BaseJpaTest {
|
||||||
@Autowired
|
@Autowired
|
||||||
protected FhirContext myFhirCtx;
|
protected FhirContext myFhirCtx;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ElasticsearchSvcImpl myElasticsearchSvc;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
protected PlatformTransactionManager myPlatformTransactionManager;
|
protected PlatformTransactionManager myPlatformTransactionManager;
|
||||||
|
|
||||||
|
@ -101,7 +105,7 @@ public class BaseR4SearchLastN extends BaseJpaTest {
|
||||||
private static final Map<String, Date> observationEffectiveMap = new HashMap<>();
|
private static final Map<String, Date> observationEffectiveMap = new HashMap<>();
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void beforeCreateTestPatientsAndObservations() {
|
public void beforeCreateTestPatientsAndObservations() throws IOException {
|
||||||
// Using a static flag to ensure that test data and elasticsearch index is only created once.
|
// Using a static flag to ensure that test data and elasticsearch index is only created once.
|
||||||
// Creating this data and the index is time consuming and as such want to avoid having to repeat for each test.
|
// Creating this data and the index is time consuming and as such want to avoid having to repeat for each test.
|
||||||
// Normally would use a static @BeforeClass method for this purpose, but Autowired objects cannot be accessed in static methods.
|
// Normally would use a static @BeforeClass method for this purpose, but Autowired objects cannot be accessed in static methods.
|
||||||
|
@ -120,6 +124,9 @@ public class BaseR4SearchLastN extends BaseJpaTest {
|
||||||
createObservationsForPatient(patient2Id);
|
createObservationsForPatient(patient2Id);
|
||||||
dataLoaded = true;
|
dataLoaded = true;
|
||||||
|
|
||||||
|
myElasticsearchSvc.refreshIndex(ElasticsearchSvcImpl.OBSERVATION_INDEX);
|
||||||
|
myElasticsearchSvc.refreshIndex(ElasticsearchSvcImpl.OBSERVATION_CODE_INDEX);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,13 +3,12 @@ package ca.uhn.fhir.jpa.dao.r4;
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao;
|
import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao;
|
||||||
import ca.uhn.fhir.jpa.config.TestR4ConfigWithElasticsearchClient;
|
import ca.uhn.fhir.jpa.config.TestR4ConfigWithElasticsearchClient;
|
||||||
import ca.uhn.fhir.jpa.dao.data.IObservationIndexedCodeCodeableConceptSearchParamDao;
|
|
||||||
import ca.uhn.fhir.jpa.dao.ObservationLastNIndexPersistSvc;
|
import ca.uhn.fhir.jpa.dao.ObservationLastNIndexPersistSvc;
|
||||||
import ca.uhn.fhir.jpa.model.entity.ObservationIndexedCodeCodeableConceptEntity;
|
|
||||||
import ca.uhn.fhir.jpa.model.entity.ObservationIndexedSearchParamLastNEntity;
|
|
||||||
import ca.uhn.fhir.jpa.dao.data.IObservationIndexedSearchParamLastNDao;
|
|
||||||
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
||||||
|
import ca.uhn.fhir.jpa.model.util.CodeSystemHash;
|
||||||
import ca.uhn.fhir.jpa.search.lastn.ElasticsearchSvcImpl;
|
import ca.uhn.fhir.jpa.search.lastn.ElasticsearchSvcImpl;
|
||||||
|
import ca.uhn.fhir.jpa.search.lastn.json.CodeJson;
|
||||||
|
import ca.uhn.fhir.jpa.search.lastn.json.ObservationJson;
|
||||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||||
import ca.uhn.fhir.parser.IParser;
|
import ca.uhn.fhir.parser.IParser;
|
||||||
import ca.uhn.fhir.rest.param.*;
|
import ca.uhn.fhir.rest.param.*;
|
||||||
|
@ -42,12 +41,6 @@ import static org.junit.Assert.assertTrue;
|
||||||
@ContextConfiguration(classes = {TestR4ConfigWithElasticsearchClient.class})
|
@ContextConfiguration(classes = {TestR4ConfigWithElasticsearchClient.class})
|
||||||
public class PersistObservationIndexedSearchParamLastNR4IT {
|
public class PersistObservationIndexedSearchParamLastNR4IT {
|
||||||
|
|
||||||
@Autowired
|
|
||||||
IObservationIndexedSearchParamLastNDao myResourceIndexedObservationLastNDao;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
IObservationIndexedCodeCodeableConceptSearchParamDao myCodeableConceptIndexedSearchParamNormalizedDao;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ElasticsearchSvcImpl elasticsearchSvc;
|
private ElasticsearchSvcImpl elasticsearchSvc;
|
||||||
|
|
||||||
|
@ -64,11 +57,10 @@ public class PersistObservationIndexedSearchParamLastNR4IT {
|
||||||
protected FhirContext myFhirCtx;
|
protected FhirContext myFhirCtx;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void before() {
|
public void before() throws IOException {
|
||||||
|
|
||||||
myResourceIndexedObservationLastNDao.deleteAll();
|
|
||||||
myCodeableConceptIndexedSearchParamNormalizedDao.deleteAll();
|
|
||||||
|
|
||||||
|
elasticsearchSvc.deleteAllDocumentsForTest(ElasticsearchSvcImpl.OBSERVATION_INDEX);
|
||||||
|
elasticsearchSvc.deleteAllDocumentsForTest(ElasticsearchSvcImpl.OBSERVATION_CODE_INDEX);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final String SINGLE_SUBJECT_ID = "4567";
|
private final String SINGLE_SUBJECT_ID = "4567";
|
||||||
|
@ -85,7 +77,7 @@ public class PersistObservationIndexedSearchParamLastNR4IT {
|
||||||
private ReferenceAndListParam multiSubjectParams = null;
|
private ReferenceAndListParam multiSubjectParams = null;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIndexObservationSingle() {
|
public void testIndexObservationSingle() throws IOException {
|
||||||
indexSingleObservation();
|
indexSingleObservation();
|
||||||
SearchParameterMap searchParameterMap = new SearchParameterMap();
|
SearchParameterMap searchParameterMap = new SearchParameterMap();
|
||||||
searchParameterMap.setLastNMax(10);
|
searchParameterMap.setLastNMax(10);
|
||||||
|
@ -124,7 +116,7 @@ public class PersistObservationIndexedSearchParamLastNR4IT {
|
||||||
assertEquals(SINGLE_OBSERVATION_PID, observationIdsOnly.get(0));
|
assertEquals(SINGLE_OBSERVATION_PID, observationIdsOnly.get(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void indexSingleObservation() {
|
private void indexSingleObservation() throws IOException {
|
||||||
|
|
||||||
Observation myObservation = new Observation();
|
Observation myObservation = new Observation();
|
||||||
IdType observationID = new IdType("Observation", SINGLE_OBSERVATION_PID, "1");
|
IdType observationID = new IdType("Observation", SINGLE_OBSERVATION_PID, "1");
|
||||||
|
@ -139,6 +131,9 @@ public class PersistObservationIndexedSearchParamLastNR4IT {
|
||||||
|
|
||||||
testObservationPersist.indexObservation(myObservation);
|
testObservationPersist.indexObservation(myObservation);
|
||||||
|
|
||||||
|
elasticsearchSvc.refreshIndex(ElasticsearchSvcImpl.OBSERVATION_INDEX);
|
||||||
|
elasticsearchSvc.refreshIndex(ElasticsearchSvcImpl.OBSERVATION_CODE_INDEX);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<CodeableConcept> getCategoryCode() {
|
private List<CodeableConcept> getCategoryCode() {
|
||||||
|
@ -179,7 +174,7 @@ public class PersistObservationIndexedSearchParamLastNR4IT {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIndexObservationMultiple() {
|
public void testIndexObservationMultiple() throws IOException {
|
||||||
indexMultipleObservations();
|
indexMultipleObservations();
|
||||||
SearchParameterMap searchParameterMap = new SearchParameterMap();
|
SearchParameterMap searchParameterMap = new SearchParameterMap();
|
||||||
searchParameterMap.setLastNMax(100);
|
searchParameterMap.setLastNMax(100);
|
||||||
|
@ -206,7 +201,7 @@ public class PersistObservationIndexedSearchParamLastNR4IT {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void indexMultipleObservations() {
|
private void indexMultipleObservations() throws IOException {
|
||||||
|
|
||||||
// Create two CodeableConcept values each for a Code with three codings.
|
// Create two CodeableConcept values each for a Code with three codings.
|
||||||
CodeableConcept codeableConceptField1 = new CodeableConcept().setText("Test Codeable Concept Field for First Code");
|
CodeableConcept codeableConceptField1 = new CodeableConcept().setText("Test Codeable Concept Field for First Code");
|
||||||
|
@ -275,10 +270,13 @@ public class PersistObservationIndexedSearchParamLastNR4IT {
|
||||||
|
|
||||||
multiSubjectParams = new ReferenceAndListParam().addAnd(subjectParams);
|
multiSubjectParams = new ReferenceAndListParam().addAnd(subjectParams);
|
||||||
|
|
||||||
|
elasticsearchSvc.refreshIndex(ElasticsearchSvcImpl.OBSERVATION_INDEX);
|
||||||
|
elasticsearchSvc.refreshIndex(ElasticsearchSvcImpl.OBSERVATION_CODE_INDEX);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDeleteObservation() {
|
public void testDeleteObservation() throws IOException {
|
||||||
indexMultipleObservations();
|
indexMultipleObservations();
|
||||||
SearchParameterMap searchParameterMap = new SearchParameterMap();
|
SearchParameterMap searchParameterMap = new SearchParameterMap();
|
||||||
searchParameterMap.setLastNMax(100);
|
searchParameterMap.setLastNMax(100);
|
||||||
|
@ -302,6 +300,7 @@ public class PersistObservationIndexedSearchParamLastNR4IT {
|
||||||
entity.setVersion(0L);
|
entity.setVersion(0L);
|
||||||
|
|
||||||
testObservationPersist.deleteObservationIndex(entity);
|
testObservationPersist.deleteObservationIndex(entity);
|
||||||
|
elasticsearchSvc.refreshIndex(ElasticsearchSvcImpl.OBSERVATION_INDEX);
|
||||||
|
|
||||||
// Confirm that observation was deleted.
|
// Confirm that observation was deleted.
|
||||||
searchParameterMap = new SearchParameterMap();
|
searchParameterMap = new SearchParameterMap();
|
||||||
|
@ -318,14 +317,16 @@ public class PersistObservationIndexedSearchParamLastNR4IT {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUpdateObservation() {
|
public void testUpdateObservation() throws IOException {
|
||||||
indexSingleObservation();
|
indexSingleObservation();
|
||||||
ObservationIndexedSearchParamLastNEntity observationIndexEntity = myResourceIndexedObservationLastNDao.findAll().get(0);
|
SearchParameterMap searchParameterMap = new SearchParameterMap();
|
||||||
|
searchParameterMap.setLastNMax(10);
|
||||||
|
ObservationJson observationIndexEntity = elasticsearchSvc.executeLastNWithAllFieldsForTest(searchParameterMap, myFhirCtx).get(0);
|
||||||
assertEquals(SINGLE_OBSERVATION_PID, observationIndexEntity.getIdentifier());
|
assertEquals(SINGLE_OBSERVATION_PID, observationIndexEntity.getIdentifier());
|
||||||
assertEquals(SINGLE_SUBJECT_ID, observationIndexEntity.getSubject());
|
assertEquals(SINGLE_SUBJECT_ID, observationIndexEntity.getSubject());
|
||||||
assertEquals(SINGLE_EFFECTIVEDTM, observationIndexEntity.getEffectiveDtm());
|
assertEquals(SINGLE_EFFECTIVEDTM, observationIndexEntity.getEffectiveDtm());
|
||||||
|
|
||||||
SearchParameterMap searchParameterMap = new SearchParameterMap();
|
searchParameterMap = new SearchParameterMap();
|
||||||
ReferenceParam subjectParam = new ReferenceParam("Patient", "", SINGLE_SUBJECT_ID);
|
ReferenceParam subjectParam = new ReferenceParam("Patient", "", SINGLE_SUBJECT_ID);
|
||||||
searchParameterMap.add(Observation.SP_SUBJECT, new ReferenceAndListParam().addAnd(new ReferenceOrListParam().addOr(subjectParam)));
|
searchParameterMap.add(Observation.SP_SUBJECT, new ReferenceAndListParam().addAnd(new ReferenceOrListParam().addOr(subjectParam)));
|
||||||
TokenParam categoryParam = new TokenParam(CATEGORYFIRSTCODINGSYSTEM, FIRSTCATEGORYFIRSTCODINGCODE);
|
TokenParam categoryParam = new TokenParam(CATEGORYFIRSTCODINGSYSTEM, FIRSTCATEGORYFIRSTCODINGCODE);
|
||||||
|
@ -350,8 +351,9 @@ public class PersistObservationIndexedSearchParamLastNR4IT {
|
||||||
updatedObservation.setCode(getObservationCode());
|
updatedObservation.setCode(getObservationCode());
|
||||||
|
|
||||||
testObservationPersist.indexObservation(updatedObservation);
|
testObservationPersist.indexObservation(updatedObservation);
|
||||||
|
elasticsearchSvc.refreshIndex(ElasticsearchSvcImpl.OBSERVATION_INDEX);
|
||||||
|
|
||||||
ObservationIndexedSearchParamLastNEntity updatedObservationEntity = myResourceIndexedObservationLastNDao.findByIdentifier(SINGLE_OBSERVATION_PID);
|
ObservationJson updatedObservationEntity = elasticsearchSvc.getObservationDocument(SINGLE_OBSERVATION_PID);
|
||||||
assertEquals("1234", updatedObservationEntity.getSubject());
|
assertEquals("1234", updatedObservationEntity.getSubject());
|
||||||
assertEquals(newEffectiveDtm.getValue(), updatedObservationEntity.getEffectiveDtm());
|
assertEquals(newEffectiveDtm.getValue(), updatedObservationEntity.getEffectiveDtm());
|
||||||
|
|
||||||
|
@ -413,6 +415,8 @@ public class PersistObservationIndexedSearchParamLastNR4IT {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
elasticsearchSvc.refreshIndex(ElasticsearchSvcImpl.OBSERVATION_INDEX);
|
||||||
|
|
||||||
SearchParameterMap searchParameterMap = new SearchParameterMap();
|
SearchParameterMap searchParameterMap = new SearchParameterMap();
|
||||||
|
|
||||||
// execute Observation ID search - Composite Aggregation
|
// execute Observation ID search - Composite Aggregation
|
||||||
|
|
|
@ -12,8 +12,6 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||||
import org.hl7.fhir.r4.model.Observation;
|
import org.hl7.fhir.r4.model.Observation;
|
||||||
import org.junit.*;
|
import org.junit.*;
|
||||||
import org.hl7.fhir.r4.model.CodeableConcept;
|
|
||||||
import org.hl7.fhir.r4.model.Coding;
|
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.test.context.ContextConfiguration;
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
@ -84,7 +82,7 @@ public class LastNElasticsearchSvcMultipleObservationsIT {
|
||||||
searchParameterMap.add(Observation.SP_SUBJECT, buildReferenceAndListParam(subjectParam));
|
searchParameterMap.add(Observation.SP_SUBJECT, buildReferenceAndListParam(subjectParam));
|
||||||
searchParameterMap.setLastNMax(3);
|
searchParameterMap.setLastNMax(3);
|
||||||
|
|
||||||
List<ObservationJson> observations = elasticsearchSvc.executeLastNWithAllFields(searchParameterMap, myFhirContext);
|
List<ObservationJson> observations = elasticsearchSvc.executeLastNWithAllFieldsForTest(searchParameterMap, myFhirContext);
|
||||||
|
|
||||||
assertEquals(60, observations.size());
|
assertEquals(60, observations.size());
|
||||||
|
|
||||||
|
@ -305,16 +303,16 @@ public class LastNElasticsearchSvcMultipleObservationsIT {
|
||||||
private void createMultiplePatientsAndObservations() throws IOException {
|
private void createMultiplePatientsAndObservations() throws IOException {
|
||||||
// Create CodeableConcepts for two Codes, each with three codings.
|
// Create CodeableConcepts for two Codes, each with three codings.
|
||||||
String codeableConceptId1 = UUID.randomUUID().toString();
|
String codeableConceptId1 = UUID.randomUUID().toString();
|
||||||
CodeableConcept codeableConceptField1 = new CodeableConcept().setText("Test Codeable Concept Field for First Code");
|
CodeJson codeJson1 = new CodeJson();
|
||||||
codeableConceptField1.addCoding(new Coding("http://mycodes.org/fhir/observation-code", "test-code-1", "test-code-1 display"));
|
codeJson1.setCodeableConceptText("Test Codeable Concept Field for First Code");
|
||||||
CodeJson codeJson1 = new CodeJson(codeableConceptField1, codeableConceptId1);
|
codeJson1.setCodeableConceptId(codeableConceptId1);
|
||||||
String codeJson1Document = ourMapperNonPrettyPrint.writeValueAsString(codeJson1);
|
codeJson1.addCoding("http://mycodes.org/fhir/observation-code", "test-code-1", "test-code-1 display");
|
||||||
|
|
||||||
String codeableConceptId2 = UUID.randomUUID().toString();
|
String codeableConceptId2 = UUID.randomUUID().toString();
|
||||||
CodeableConcept codeableConceptField2 = new CodeableConcept().setText("Test Codeable Concept Field for Second Code");
|
CodeJson codeJson2 = new CodeJson();
|
||||||
codeableConceptField2.addCoding(new Coding("http://mycodes.org/fhir/observation-code", "test-code-2", "test-code-2 display"));
|
codeJson2.setCodeableConceptText("Test Codeable Concept Field for Second Code");
|
||||||
CodeJson codeJson2 = new CodeJson(codeableConceptField2, codeableConceptId2);
|
codeJson2.setCodeableConceptId(codeableConceptId1);
|
||||||
String codeJson2Document = ourMapperNonPrettyPrint.writeValueAsString(codeJson2);
|
codeJson2.addCoding("http://mycodes.org/fhir/observation-code", "test-code-2", "test-code-2 display");
|
||||||
|
|
||||||
// Create CodeableConcepts for two categories, each with three codings.
|
// Create CodeableConcepts for two categories, each with three codings.
|
||||||
// Create three codings and first category CodeableConcept
|
// Create three codings and first category CodeableConcept
|
||||||
|
|
|
@ -17,8 +17,6 @@ import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
import com.fasterxml.jackson.core.JsonGenerator;
|
import com.fasterxml.jackson.core.JsonGenerator;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||||
import org.hl7.fhir.r4.model.CodeableConcept;
|
|
||||||
import org.hl7.fhir.r4.model.Coding;
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -92,8 +90,8 @@ public class LastNElasticsearchSvcSingleObservationIT {
|
||||||
|
|
||||||
@After
|
@After
|
||||||
public void after() throws IOException {
|
public void after() throws IOException {
|
||||||
elasticsearchSvc.deleteAllDocuments(ElasticsearchSvcImpl.OBSERVATION_INDEX);
|
elasticsearchSvc.deleteAllDocumentsForTest(ElasticsearchSvcImpl.OBSERVATION_INDEX);
|
||||||
elasticsearchSvc.deleteAllDocuments(ElasticsearchSvcImpl.OBSERVATION_CODE_INDEX);
|
elasticsearchSvc.deleteAllDocumentsForTest(ElasticsearchSvcImpl.OBSERVATION_CODE_INDEX);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -118,7 +116,7 @@ public class LastNElasticsearchSvcSingleObservationIT {
|
||||||
assertEquals(RESOURCEPID, observationIdsOnly.get(0));
|
assertEquals(RESOURCEPID, observationIdsOnly.get(0));
|
||||||
|
|
||||||
// execute Observation search for all search fields
|
// execute Observation search for all search fields
|
||||||
List<ObservationJson> observations = elasticsearchSvc.executeLastNWithAllFields(searchParameterMap, myFhirContext);
|
List<ObservationJson> observations = elasticsearchSvc.executeLastNWithAllFieldsForTest(searchParameterMap, myFhirContext);
|
||||||
|
|
||||||
validateFullObservationSearch(observations);
|
validateFullObservationSearch(observations);
|
||||||
}
|
}
|
||||||
|
@ -226,7 +224,7 @@ public class LastNElasticsearchSvcSingleObservationIT {
|
||||||
assertEquals(String.valueOf(CodeSystemHash.hashCodeSystem(CODEFIRSTCODINGSYSTEM, CODEFIRSTCODINGCODE)), code_coding_code_system_hash);
|
assertEquals(String.valueOf(CodeSystemHash.hashCodeSystem(CODEFIRSTCODINGSYSTEM, CODEFIRSTCODINGCODE)), code_coding_code_system_hash);
|
||||||
|
|
||||||
// Retrieve all Observation codes
|
// Retrieve all Observation codes
|
||||||
List<CodeJson> codes = elasticsearchSvc.queryAllIndexedObservationCodes();
|
List<CodeJson> codes = elasticsearchSvc.queryAllIndexedObservationCodesForTest();
|
||||||
assertEquals(1, codes.size());
|
assertEquals(1, codes.size());
|
||||||
CodeJson persistedObservationCode = codes.get(0);
|
CodeJson persistedObservationCode = codes.get(0);
|
||||||
|
|
||||||
|
@ -261,51 +259,44 @@ public class LastNElasticsearchSvcSingleObservationIT {
|
||||||
indexedObservation.setEffectiveDtm(EFFECTIVEDTM);
|
indexedObservation.setEffectiveDtm(EFFECTIVEDTM);
|
||||||
|
|
||||||
// Add three CodeableConcepts for category
|
// Add three CodeableConcepts for category
|
||||||
List<CodeableConcept> categoryConcepts = new ArrayList<>();
|
List<CodeJson> categoryConcepts = new ArrayList<>();
|
||||||
// Create three codings and first category CodeableConcept
|
// Create three codings and first category CodeableConcept
|
||||||
List<Coding> category1 = new ArrayList<>();
|
CodeJson categoryCodeableConcept1 = new CodeJson();
|
||||||
CodeableConcept categoryCodeableConcept1 = new CodeableConcept().setText(FIRSTCATEGORYTEXT);
|
categoryCodeableConcept1.setCodeableConceptText(FIRSTCATEGORYTEXT);
|
||||||
category1.add(new Coding(CATEGORYFIRSTCODINGSYSTEM, FIRSTCATEGORYFIRSTCODINGCODE, FIRSTCATEGORYFIRSTCODINGDISPLAY));
|
categoryCodeableConcept1.addCoding(CATEGORYFIRSTCODINGSYSTEM, FIRSTCATEGORYFIRSTCODINGCODE, FIRSTCATEGORYFIRSTCODINGDISPLAY);
|
||||||
category1.add(new Coding(CATEGORYSECONDCODINGSYSTEM, FIRSTCATEGORYSECONDCODINGCODE, FIRSTCATEGORYSECONDCODINGDISPLAY));
|
categoryCodeableConcept1.addCoding(CATEGORYSECONDCODINGSYSTEM, FIRSTCATEGORYSECONDCODINGCODE, FIRSTCATEGORYSECONDCODINGDISPLAY);
|
||||||
category1.add(new Coding(CATEGORYTHIRDCODINGSYSTEM, FIRSTCATEGORYTHIRDCODINGCODE, FIRSTCATEGORYTHIRDCODINGDISPLAY));
|
categoryCodeableConcept1.addCoding(CATEGORYTHIRDCODINGSYSTEM, FIRSTCATEGORYTHIRDCODINGCODE, FIRSTCATEGORYTHIRDCODINGDISPLAY);
|
||||||
categoryCodeableConcept1.setCoding(category1);
|
|
||||||
categoryConcepts.add(categoryCodeableConcept1);
|
categoryConcepts.add(categoryCodeableConcept1);
|
||||||
// Create three codings and second category CodeableConcept
|
// Create three codings and second category CodeableConcept
|
||||||
List<Coding> category2 = new ArrayList<>();
|
CodeJson categoryCodeableConcept2 = new CodeJson();
|
||||||
CodeableConcept categoryCodeableConcept2 = new CodeableConcept().setText(SECONDCATEGORYTEXT);
|
categoryCodeableConcept2.setCodeableConceptText(SECONDCATEGORYTEXT);
|
||||||
category2.add(new Coding(CATEGORYFIRSTCODINGSYSTEM, SECONDCATEGORYFIRSTCODINGCODE, SECONDCATEGORYFIRSTCODINGDISPLAY));
|
categoryCodeableConcept2.addCoding(CATEGORYFIRSTCODINGSYSTEM, SECONDCATEGORYFIRSTCODINGCODE, SECONDCATEGORYFIRSTCODINGDISPLAY);
|
||||||
category2.add(new Coding(CATEGORYSECONDCODINGSYSTEM, SECONDCATEGORYSECONDCODINGCODE, SECONDCATEGORYSECONDCODINGDISPLAY));
|
categoryCodeableConcept2.addCoding(CATEGORYSECONDCODINGSYSTEM, SECONDCATEGORYSECONDCODINGCODE, SECONDCATEGORYSECONDCODINGDISPLAY);
|
||||||
category2.add(new Coding(CATEGORYTHIRDCODINGSYSTEM, SECONDCATEGORYTHIRDCODINGCODE, SECONDCATEGORYTHIRDCODINGDISPLAY));
|
categoryCodeableConcept2.addCoding(CATEGORYTHIRDCODINGSYSTEM, SECONDCATEGORYTHIRDCODINGCODE, SECONDCATEGORYTHIRDCODINGDISPLAY);
|
||||||
categoryCodeableConcept2.setCoding(category2);
|
|
||||||
categoryConcepts.add(categoryCodeableConcept2);
|
categoryConcepts.add(categoryCodeableConcept2);
|
||||||
// Create three codings and third category CodeableConcept
|
// Create three codings and third category CodeableConcept
|
||||||
List<Coding> category3 = new ArrayList<>();
|
CodeJson categoryCodeableConcept3 = new CodeJson();
|
||||||
CodeableConcept categoryCodeableConcept3 = new CodeableConcept().setText(THIRDCATEGORYTEXT);
|
categoryCodeableConcept3.setCodeableConceptText(THIRDCATEGORYTEXT);
|
||||||
category3.add(new Coding(CATEGORYFIRSTCODINGSYSTEM, THIRDCATEGORYFIRSTCODINGCODE, THIRDCATEGORYFIRSTCODINGDISPLAY));
|
categoryCodeableConcept3.addCoding(CATEGORYFIRSTCODINGSYSTEM, THIRDCATEGORYFIRSTCODINGCODE, THIRDCATEGORYFIRSTCODINGDISPLAY);
|
||||||
category3.add(new Coding(CATEGORYSECONDCODINGSYSTEM, THIRDCATEGORYSECONDCODINGCODE, THIRDCATEGORYSECONDCODINGDISPLAY));
|
categoryCodeableConcept3.addCoding(CATEGORYSECONDCODINGSYSTEM, THIRDCATEGORYSECONDCODINGCODE, THIRDCATEGORYSECONDCODINGDISPLAY);
|
||||||
category3.add(new Coding(CATEGORYTHIRDCODINGSYSTEM, THIRDCATEGORYTHIRDCODINGCODE, THIRDCATEGORYTHIRDCODINGDISPLAY));
|
categoryCodeableConcept3.addCoding(CATEGORYTHIRDCODINGSYSTEM, THIRDCATEGORYTHIRDCODINGCODE, THIRDCATEGORYTHIRDCODINGDISPLAY);
|
||||||
categoryCodeableConcept3.setCoding(category3);
|
|
||||||
categoryConcepts.add(categoryCodeableConcept3);
|
categoryConcepts.add(categoryCodeableConcept3);
|
||||||
indexedObservation.setCategories(categoryConcepts);
|
indexedObservation.setCategories(categoryConcepts);
|
||||||
|
|
||||||
// Create CodeableConcept for Code with three codings.
|
// Create CodeableConcept for Code with three codings.
|
||||||
indexedObservation.setCode_concept_id(OBSERVATIONSINGLECODEID);
|
indexedObservation.setCode_concept_id(OBSERVATIONSINGLECODEID);
|
||||||
CodeableConcept codeableConceptField = new CodeableConcept().setText(OBSERVATIONCODETEXT);
|
CodeJson codeableConceptField = new CodeJson();
|
||||||
codeableConceptField.addCoding(new Coding(CODEFIRSTCODINGSYSTEM, CODEFIRSTCODINGCODE, CODEFIRSTCODINGDISPLAY));
|
codeableConceptField.setCodeableConceptText(OBSERVATIONCODETEXT);
|
||||||
|
codeableConceptField.addCoding(CODEFIRSTCODINGSYSTEM, CODEFIRSTCODINGCODE, CODEFIRSTCODINGDISPLAY);
|
||||||
indexedObservation.setCode(codeableConceptField);
|
indexedObservation.setCode(codeableConceptField);
|
||||||
|
|
||||||
assertTrue(elasticsearchSvc.createOrUpdateObservationIndex(RESOURCEPID, indexedObservation));
|
assertTrue(elasticsearchSvc.createOrUpdateObservationIndex(RESOURCEPID, indexedObservation));
|
||||||
|
|
||||||
CodeJson observationCode = new CodeJson(codeableConceptField, OBSERVATIONSINGLECODEID);
|
codeableConceptField.setCodeableConceptId(OBSERVATIONSINGLECODEID);
|
||||||
String codeDocument = ourMapperNonPrettyPrint.writeValueAsString(observationCode);
|
assertTrue(elasticsearchSvc.createOrUpdateObservationCodeIndex(OBSERVATIONSINGLECODEID, codeableConceptField));
|
||||||
assertTrue(elasticsearchSvc.performIndex(ElasticsearchSvcImpl.OBSERVATION_CODE_INDEX, OBSERVATIONSINGLECODEID, codeDocument, ElasticsearchSvcImpl.CODE_DOCUMENT_TYPE));
|
|
||||||
|
|
||||||
try {
|
|
||||||
Thread.sleep(1000L);
|
|
||||||
} catch (InterruptedException theE) {
|
|
||||||
theE.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
elasticsearchSvc.refreshIndex(ElasticsearchSvcImpl.OBSERVATION_INDEX);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,63 +0,0 @@
|
||||||
package ca.uhn.fhir.jpa.model.entity;
|
|
||||||
|
|
||||||
/*-
|
|
||||||
* #%L
|
|
||||||
* HAPI FHIR Model
|
|
||||||
* %%
|
|
||||||
* Copyright (C) 2014 - 2020 University Health Network
|
|
||||||
* %%
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
|
|
||||||
import ca.uhn.fhir.jpa.model.util.CodeSystemHash;
|
|
||||||
import org.hibernate.search.annotations.Analyze;
|
|
||||||
import org.hibernate.search.annotations.Field;
|
|
||||||
|
|
||||||
import javax.persistence.*;
|
|
||||||
|
|
||||||
@Entity
|
|
||||||
@Embeddable
|
|
||||||
@Table(name = "HFJ_SPIDX_LASTN_CODING")
|
|
||||||
public class ObservationIndexedCodeCodingEntity {
|
|
||||||
|
|
||||||
public static final int MAX_LENGTH = 200;
|
|
||||||
|
|
||||||
@Id
|
|
||||||
@Column(name = "CODEABLE_CONCEPT_ID", length = MAX_LENGTH)
|
|
||||||
private String myCodeableConceptId;
|
|
||||||
|
|
||||||
@Field(name = "code", analyze = Analyze.NO)
|
|
||||||
private String myCode;
|
|
||||||
|
|
||||||
@Field(name = "system", analyze = Analyze.NO)
|
|
||||||
private String mySystem;
|
|
||||||
|
|
||||||
@Field(name = "code_system_hash", analyze = Analyze.NO)
|
|
||||||
private String myCodeSystemHash;
|
|
||||||
|
|
||||||
@Field(name = "display")
|
|
||||||
private String myDisplay;
|
|
||||||
|
|
||||||
public ObservationIndexedCodeCodingEntity() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public ObservationIndexedCodeCodingEntity(String theSystem, String theCode, String theDisplay, String theCodeableConceptId) {
|
|
||||||
myCode = theCode;
|
|
||||||
mySystem = theSystem;
|
|
||||||
myCodeSystemHash = String.valueOf(CodeSystemHash.hashCodeSystem(theSystem, theCode));
|
|
||||||
myDisplay = theDisplay;
|
|
||||||
myCodeableConceptId = theCodeableConceptId;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in New Issue