Skip to content

Commit

Permalink
Add search sorting: active, PT word count + alpha.
Browse files Browse the repository at this point in the history
  • Loading branch information
kaicode committed Jul 6, 2023
1 parent d0a9442 commit 0abedb4
Show file tree
Hide file tree
Showing 26 changed files with 464 additions and 86 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.*
target
lucene-index
test-lucene-index
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<parent>
<groupId>org.snomed</groupId>
<artifactId>snomed-parent-bom</artifactId>
<version>1.0.9</version>
<version>1.0.11-SNAPSHOT</version>
</parent>

<properties>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,30 +1,19 @@
package org.snomed.snowstormmicro;

import org.apache.logging.log4j.util.Strings;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.store.NIOFSDirectory;
import org.hibernate.service.spi.ServiceException;
import org.ihtsdo.otf.snomedboot.ReleaseImportException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.snomed.snowstormmicro.loading.ImportService;
import org.snomed.snowstormmicro.service.CodeSystemService;
import org.snomed.snowstormmicro.service.ValueSetService;
import org.snomed.snowstormmicro.util.TimerUtil;
import org.snomed.snowstormmicro.service.AppSetupService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration;
import org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Set;
import java.util.stream.Collectors;

@SpringBootApplication(
exclude = {
Expand All @@ -35,38 +24,20 @@
)
public class SnowstormMicroApplication implements CommandLineRunner {

@Value("${load}")
private String loadReleaseArchives;

@Autowired
private ImportService importService;

@Autowired
private CodeSystemService codeSystemService;

@Autowired
private ValueSetService valueSetService;
private AppSetupService appSetupService;

private final Logger logger = LoggerFactory.getLogger(getClass());

@Override
public void run(String... args) throws IOException {
if (!Strings.isEmpty(loadReleaseArchives)) {
Set<String> filePaths = Arrays.stream(loadReleaseArchives.split(",")).collect(Collectors.toSet());
try {
TimerUtil timer = new TimerUtil("Import");
importService.importRelease(filePaths);
timer.finish();
logger.info("Import complete");
public void run(String... args) {
try {
if (appSetupService.run()) {
System.exit(0);
} catch (ReleaseImportException | IOException e) {
logger.error("Import failed", e);
System.exit(1);
}
} else {
IndexSearcher indexSearcher = new IndexSearcher(DirectoryReader.open(new NIOFSDirectory(new File("lucene-index").toPath())));
codeSystemService.setIndexSearcher(indexSearcher);
valueSetService.setIndexSearcher(indexSearcher);
} catch (ServiceException | IOException | ReleaseImportException e) {
logger.error(e.getMessage(), e);
System.exit(1);
}
}

Expand Down
12 changes: 9 additions & 3 deletions src/main/java/org/snomed/snowstormmicro/domain/Concept.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,17 @@ public class Concept {
public static final String DOC_TYPE = "concept";

public interface FieldNames {

String ID = "id";
String ACTIVE = "active";
String ACTIVE_SORT = "active_sort";
String ANCESTORS = "ancestors";
String MEMBERSHIP = "membership";
String TERM = "term";
String TERM_STORED = "term_stored";
String PT_TERM_LENGTH = "pt_term_score";
String PT_WORD_COUNT = "pt_word_count";
String PT_STORED = "pt_stored";
String PT = "pt";
}
private String conceptId;
private boolean active;
Expand All @@ -34,9 +39,10 @@ public Concept(String conceptId, boolean active) {
}

public String getPT() {
// TODO: fix
for (Description description : descriptions) {
return description.getTerm();
if (!description.isFsn() && !description.getPreferredLangRefsets().isEmpty()) {
return description.getTerm();
}
}
return null;
}
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/org/snomed/snowstormmicro/domain/Concepts.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,6 @@ public class Concepts {
public static final String IS_A = "116680003";
public static final String INFERRED_RELATIONSHIP = "900000000000011006";

public static final String PREFERRED = "900000000000548007";
public static final String ACCEPTABLE = "900000000000549004";
}
21 changes: 9 additions & 12 deletions src/main/java/org/snomed/snowstormmicro/domain/Description.java
Original file line number Diff line number Diff line change
@@ -1,29 +1,26 @@
package org.snomed.snowstormmicro.domain;

import java.util.HashMap;
import java.util.Map;
import java.util.HashSet;
import java.util.Set;

public class Description {

private String id;
private String term;
private String lang;
private boolean fsn;
private Map<String, String> acceptability;
private Set<String> preferredLangRefsets;

public Description() {
preferredLangRefsets = new HashSet<>();
}

public Description(String id, String languageCode, boolean fsn, String term) {
this();
this.id = id;
this.lang = languageCode;
this.fsn = fsn;
this.term = term;
acceptability = new HashMap<>();
}

public Description(String term) {
this.term = term;
}

public String getId() {
Expand Down Expand Up @@ -54,11 +51,11 @@ public void setFsn(boolean fsn) {
this.fsn = fsn;
}

public Map<String, String> getAcceptability() {
return acceptability;
public Set<String> getPreferredLangRefsets() {
return preferredLangRefsets;
}

public void setAcceptability(Map<String, String> acceptability) {
this.acceptability = acceptability;
public void setPreferredLangRefsets(Set<String> preferredLangRefsets) {
this.preferredLangRefsets = preferredLangRefsets;
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package org.snomed.snowstormmicro.fhir;

import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.OptionalParam;
import ca.uhn.fhir.rest.annotation.Read;
import ca.uhn.fhir.rest.annotation.Search;
import ca.uhn.fhir.rest.server.IResourceProvider;
import org.hl7.fhir.r4.model.CodeSystem;
import org.hl7.fhir.r4.model.IdType;
import org.snomed.snowstormmicro.service.CodeSystemService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
Expand All @@ -18,15 +22,33 @@ public class CodeSystemProvider implements IResourceProvider {
private CodeSystemService codeSystemService;

@Search
public List<CodeSystem> findCodeSystems() throws IOException {
public List<CodeSystem> findCodeSystems(
@OptionalParam(name="id") String id,
@OptionalParam(name="url") String url) throws IOException {
List<CodeSystem> codeSystems = new ArrayList<>();
org.snomed.snowstormmicro.domain.CodeSystem codeSystem = codeSystemService.getCodeSystem();
if (codeSystem != null) {
codeSystems.add(codeSystem.toHapi());
CodeSystem hapi = codeSystem.toHapi();
if ((id == null || hapi.getId().equals(id)) && (url == null || hapi.getUrl().equals(url))) {
codeSystems.add(hapi);
}
}
return codeSystems;
}

@Read()
public CodeSystem getCodeSystem(@IdParam IdType id) throws IOException {
String idPart = id.getIdPart();
org.snomed.snowstormmicro.domain.CodeSystem codeSystem = codeSystemService.getCodeSystem();
if (codeSystem != null) {
CodeSystem hapi = codeSystem.toHapi();
if (hapi.getId().equals(idPart)) {
return hapi;
}
}
return null;
}

@Override
public Class<CodeSystem> getResourceType() {
return CodeSystem.class;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@
import java.util.Collections;

@ResourceDef(name="TerminologyCapabilities", profile="http:https://hl7.org/fhir/StructureDefinition/TerminologyCapabilities")
@ChildOrder(names={"url", "version", "name", "title", "status", "experimental", "date", "publisher", "contact", "description", "useContext", "jurisdiction", "purpose", "copyright", "kind", "software", "implementation", "lockedDate", "codeSystem", "expansion", "codeSearch", "validateCode", "translation", "closure"})
@ChildOrder(names={"url", "version", "name", "title", "status", "experimental", "date", "publisher", "contact", "description", "useContext",
"jurisdiction", "purpose", "copyright", "kind", "software", "implementation", "lockedDate", "codeSystem", "expansion", "codeSearch",
"validateCode", "translation", "closure"})
public class FHIRTerminologyCapabilities extends TerminologyCapabilities implements IBaseConformance {

private static final long serialVersionUID = 1L;

public FHIRTerminologyCapabilities withDefaults() {
setContact();
setCodeSystem();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.OperationParam;
import ca.uhn.fhir.rest.annotation.Search;
import ca.uhn.fhir.rest.server.IResourceProvider;
import org.hl7.fhir.r4.model.IntegerType;
import org.hl7.fhir.r4.model.OperationOutcome;
Expand All @@ -12,6 +13,9 @@
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import static org.snomed.snowstormmicro.fhir.FHIRHelper.exception;

Expand All @@ -21,6 +25,11 @@ public class ValueSetProvider implements IResourceProvider {
@Autowired
private ValueSetService valueSetService;

@Search
public List<ValueSet> search() {
return Collections.emptyList();
}

@Operation(name = "$expand", idempotent = true)
public ValueSet expand(
@OperationParam(name="url") UriType url,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,37 @@
import org.snomed.snowstormmicro.domain.Description;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ComponentFactoryImpl extends ImpotentComponentFactory {

private final Map<Long, Concept> conceptMap;
private final Map<Long, Description> descriptionSynonymMap;
private final Concept dummyConcept;
private Integer maxDate = null;

public ComponentFactoryImpl() {
conceptMap = new HashMap<>();
descriptionSynonymMap = new HashMap<>();
dummyConcept = new Concept();
}

@Override
public void newConceptState(String conceptId, String effectiveTime, String active, String moduleId, String definitionStatusId) {
conceptMap.put(Long.parseLong(conceptId), new Concept(conceptId, active.equals("1")));
collectMaxEffectiveTime(effectiveTime);
}

@Override
public void newDescriptionState(String id, String effectiveTime, String active, String moduleId, String conceptId, String languageCode, String typeId, String term, String caseSignificanceId) {
if (active.equals("1") && (typeId.equals(Concepts.FSN) || typeId.equals(Concepts.SYNONYM))) {
conceptMap.getOrDefault(Long.parseLong(conceptId), dummyConcept).addDescription(new Description(id, languageCode, typeId.equals(Concepts.FSN), term));
Description description = new Description(id, languageCode, typeId.equals(Concepts.FSN), term);
conceptMap.getOrDefault(Long.parseLong(conceptId), dummyConcept).addDescription(description);
if (typeId.equals(Concepts.SYNONYM)) {
descriptionSynonymMap.put(Long.parseLong(id), description);
}
}
collectMaxEffectiveTime(effectiveTime);
}

@Override
Expand All @@ -40,6 +47,7 @@ public void newRelationshipState(String id, String effectiveTime, String active,
conceptMap.getOrDefault(Long.parseLong(sourceId), dummyConcept).addParent(parent);
}
}
collectMaxEffectiveTime(effectiveTime);
}

@Override
Expand All @@ -48,16 +56,18 @@ public void newReferenceSetMemberState(String[] fieldNames, String id, String ef
if (fieldNames.length == 0) {
// Active simple refset member
conceptMap.getOrDefault(Long.parseLong(referencedComponentId), dummyConcept).addMembership(refsetId);
} else if (fieldNames.length == 1 && fieldNames[0].equals("acceptabilityId")) {
} else if (fieldNames.length == 7 && fieldNames[6].equals("acceptabilityId") && otherValues[0].equals(Concepts.PREFERRED)) {
// Active lang refset member
List<Description> descriptions = conceptMap.getOrDefault(Long.parseLong(referencedComponentId), dummyConcept).getDescriptions();
for (Description description : descriptions) {
if (description.getId().equals(referencedComponentId)) {
description.getAcceptability().put(refsetId, otherValues[0]);
}
Description description = descriptionSynonymMap.get(Long.parseLong(referencedComponentId));
if (description != null) {
description.getPreferredLangRefsets().add(refsetId);
}
}
}
collectMaxEffectiveTime(effectiveTime);
}

private void collectMaxEffectiveTime(String effectiveTime) {
if (maxDate == null || (effectiveTime != null && Integer.parseInt(effectiveTime) > maxDate)) {
maxDate = Integer.parseInt(effectiveTime);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import org.slf4j.LoggerFactory;
import org.snomed.snowstormmicro.service.CodeSystemService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.FileSystemUtils;

Expand All @@ -27,6 +28,9 @@ public class ImportService {
@Autowired
private CodeSystemService codeSystemService;

@Value("${index.path}")
private String indexPath;

private final Logger logger = LoggerFactory.getLogger(getClass());

private final LoadingProfile loadingProfile = LoadingProfile.light
Expand All @@ -45,7 +49,7 @@ public void importRelease(Set<String> releaseArchivePaths) throws IOException, R
}

ReleaseImporter releaseImporter = new ReleaseImporter();
File luceneIndex = new File("lucene-index");
File luceneIndex = new File(indexPath);
if (luceneIndex.exists()) {
logger.info("Deleting existing index directory.");
FileSystemUtils.deleteRecursively(luceneIndex);
Expand Down
Loading

0 comments on commit 0abedb4

Please sign in to comment.