use of com.b2international.snowowl.snomed.datastore.index.entry.SnomedConceptDocument in project snow-owl by b2ihealthcare.
the class SnomedDescendantsExpander method expand.
@Override
protected void expand(List<SnomedConcept> results, final Set<String> conceptIds, Options descendantExpandOptions, boolean direct) {
try {
final int limit = getLimit(descendantExpandOptions);
final ExpressionBuilder expression = Expressions.builder();
expression.filter(active());
final ExpressionBuilder descendantFilter = Expressions.builder();
if (stated) {
descendantFilter.should(statedParents(conceptIds));
if (!direct) {
descendantFilter.should(statedAncestors(conceptIds));
}
} else {
descendantFilter.should(parents(conceptIds));
if (!direct) {
descendantFilter.should(ancestors(conceptIds));
}
}
expression.filter(descendantFilter.build());
final Query<SnomedConceptDocument> query = Query.select(SnomedConceptDocument.class).where(expression.build()).limit((conceptIds.size() == 1 && limit == 0) ? limit : Integer.MAX_VALUE).build();
final RevisionSearcher searcher = context().service(RevisionSearcher.class);
final Hits<SnomedConceptDocument> hits = searcher.search(query);
if (hits.getTotal() < 1) {
final SnomedConcepts descendants = new SnomedConcepts(0, 0);
for (SnomedConcept concept : results) {
if (stated) {
concept.setStatedDescendants(descendants);
} else {
concept.setDescendants(descendants);
}
}
return;
}
// XXX won't work if number of results is greater than one, either use custom ConceptSearch or figure out how to expand descendants effectively
if (conceptIds.size() == 1 && limit == 0) {
for (SnomedConcept concept : results) {
final SnomedConcepts descendants = new SnomedConcepts(0, hits.getTotal());
if (stated) {
concept.setStatedDescendants(descendants);
} else {
concept.setDescendants(descendants);
}
}
return;
}
final Multimap<String, String> descendantsByAncestor = TreeMultimap.create();
for (SnomedConceptDocument hit : hits) {
final Set<String> parentsAndAncestors = newHashSet();
if (stated) {
parentsAndAncestors.addAll(LongSets.toStringSet(hit.getStatedParents()));
if (!direct) {
parentsAndAncestors.addAll(LongSets.toStringSet(hit.getStatedAncestors()));
}
} else {
parentsAndAncestors.addAll(LongSets.toStringSet(hit.getParents()));
if (!direct) {
parentsAndAncestors.addAll(LongSets.toStringSet(hit.getAncestors()));
}
}
parentsAndAncestors.retainAll(conceptIds);
for (String ancestor : parentsAndAncestors) {
descendantsByAncestor.put(ancestor, hit.getId());
}
}
final Collection<String> componentIds = newHashSet(descendantsByAncestor.values());
if (limit > 0 && !componentIds.isEmpty()) {
// query descendants again
final SnomedConcepts descendants = SnomedRequests.prepareSearchConcept().all().filterByIds(componentIds).setLocales(locales()).setExpand(descendantExpandOptions.get("expand", Options.class)).build().execute(context());
final Map<String, SnomedConcept> descendantsById = newHashMap();
descendantsById.putAll(Maps.uniqueIndex(descendants, SnomedConcept::getId));
for (SnomedConcept concept : results) {
final Collection<String> descendantIds = descendantsByAncestor.get(concept.getId());
final List<SnomedConcept> currentDescendants = FluentIterable.from(descendantIds).limit(limit).transform(Functions.forMap(descendantsById)).toList();
final SnomedConcepts descendantConcepts = new SnomedConcepts(currentDescendants, null, limit, descendantIds.size());
if (stated) {
concept.setStatedDescendants(descendantConcepts);
} else {
concept.setDescendants(descendantConcepts);
}
}
} else {
for (SnomedConcept concept : results) {
final Collection<String> descendantIds = descendantsByAncestor.get(concept.getId());
final SnomedConcepts descendants = new SnomedConcepts(limit, descendantIds.size());
if (stated) {
concept.setStatedDescendants(descendants);
} else {
concept.setDescendants(descendants);
}
}
}
} catch (IOException e) {
throw SnowowlRuntimeException.wrap(e);
}
}
use of com.b2international.snowowl.snomed.datastore.index.entry.SnomedConceptDocument in project snow-owl by b2ihealthcare.
the class DetachedContainerChangeProcessor method process.
@Override
public void process(StagingArea staging, RevisionSearcher searcher) throws IOException {
final Set<String> deletedCoreComponentIds = newHashSet();
final Set<String> deletedConceptIds = newHashSet();
staging.getRemovedObjects().forEach(detachedObject -> {
if (detachedObject instanceof SnomedComponentDocument) {
String id = ((SnomedComponentDocument) detachedObject).getId();
deletedCoreComponentIds.add(id);
if (detachedObject instanceof SnomedConceptDocument) {
deletedConceptIds.add(id);
}
}
});
if (deletedCoreComponentIds.isEmpty() && deletedConceptIds.isEmpty()) {
return;
}
// deleting concepts should delete all of its descriptions, relationships, and inbound relationships
Query.select(SnomedDescriptionIndexEntry.class).where(SnomedDescriptionIndexEntry.Expressions.concepts(deletedConceptIds)).limit(PAGE_SIZE).build().stream(searcher).flatMap(Hits::stream).forEachOrdered(description -> {
deletedCoreComponentIds.add(description.getId());
stageRemove(description);
});
Query.select(SnomedRelationshipIndexEntry.class).where(Expressions.builder().should(SnomedRelationshipIndexEntry.Expressions.sourceIds(deletedConceptIds)).should(SnomedRelationshipIndexEntry.Expressions.destinationIds(deletedConceptIds)).build()).limit(PAGE_SIZE).build().stream(searcher).flatMap(Hits::stream).forEachOrdered(relationship -> {
deletedCoreComponentIds.add(relationship.getId());
stageRemove(relationship);
});
// deleting core components should delete all referring members as well
ExpressionBuilder referringMembersQuery = Expressions.builder().should(SnomedRefSetMemberIndexEntry.Expressions.referencedComponentIds(deletedCoreComponentIds)).should(SnomedRefSetMemberIndexEntry.Expressions.refsetIds(deletedConceptIds));
SnomedRf2Headers.MEMBER_FIELDS_WITH_COMPONENT_ID.forEach(memberField -> {
referringMembersQuery.should(Expressions.matchAny(memberField, deletedCoreComponentIds));
});
Query.select(SnomedRefSetMemberIndexEntry.class).where(referringMembersQuery.build()).limit(PAGE_SIZE).build().stream(searcher).flatMap(Hits::stream).forEachOrdered(member -> stageRemove(member));
}
use of com.b2international.snowowl.snomed.datastore.index.entry.SnomedConceptDocument in project snow-owl by b2ihealthcare.
the class ConceptChangeProcessorAxiomTest method deleteEmpty.
@Test
public void deleteEmpty() throws Exception {
final SnomedConceptDocument concept = concept().activeMemberOf(Collections.singleton(Concepts.REFSET_OWL_AXIOM)).memberOf(Collections.singleton(Concepts.REFSET_OWL_AXIOM)).build();
final SnomedRefSetMemberIndexEntry member = createOwlAxiom(concept.getId(), "").build();
indexRevision(MAIN, concept, member);
stageRemove(member);
final ConceptChangeProcessor processor = process();
assertEquals(1, processor.getChangedMappings().size());
final SnomedConceptDocument expected = docWithDefaults(concept).build();
final Revision actual = Iterables.getOnlyElement(processor.getChangedMappings().values()).getNewRevision();
assertDocEquals(expected, actual);
assertEquals(0, processor.getNewMappings().size());
assertEquals(0, processor.getDeletions().size());
}
use of com.b2international.snowowl.snomed.datastore.index.entry.SnomedConceptDocument in project snow-owl by b2ihealthcare.
the class ConceptChangeProcessorAxiomTest method newSubClassOfAxiom_TwoTargets.
@Test
public void newSubClassOfAxiom_TwoTargets() throws Exception {
SnomedConceptDocument concept = concept().build();
SnomedConceptDocument parentConcept = concept().build();
SnomedConceptDocument parentConcept2 = concept().build();
indexRevision(MAIN, concept, parentConcept, parentConcept2);
statedChangedConceptIds.add(Long.parseLong(concept.getId()));
statedChangedConceptIds.add(Long.parseLong(parentConcept.getId()));
statedChangedConceptIds.add(Long.parseLong(parentConcept2.getId()));
SnomedRefSetMemberIndexEntry member = createOwlAxiom(concept.getId(), String.format("SubClassOf(:%s ObjectIntersectionOf(:%s :%s))", concept.getId(), parentConcept.getId(), parentConcept2.getId())).build();
stageNew(member);
final ConceptChangeProcessor processor = process();
assertEquals(1, processor.getChangedMappings().size());
final SnomedConceptDocument expected = docWithDefaults(concept).statedParents(Long.parseLong(parentConcept.getId()), Long.parseLong(parentConcept2.getId())).statedAncestors(IComponent.ROOT_IDL).activeMemberOf(Collections.singleton(Concepts.REFSET_OWL_AXIOM)).memberOf(Collections.singleton(Concepts.REFSET_OWL_AXIOM)).build();
final Revision actual = Iterables.getOnlyElement(processor.getChangedMappings().values()).getNewRevision();
assertDocEquals(expected, actual);
assertEquals(0, processor.getNewMappings().size());
assertEquals(0, processor.getDeletions().size());
}
use of com.b2international.snowowl.snomed.datastore.index.entry.SnomedConceptDocument in project snow-owl by b2ihealthcare.
the class ConceptChangeProcessorAxiomTest method updateEmptyAxiom.
@Test
public void updateEmptyAxiom() throws Exception {
SnomedConceptDocument concept = concept().activeMemberOf(Collections.singleton(Concepts.REFSET_OWL_AXIOM)).memberOf(Collections.singleton(Concepts.REFSET_OWL_AXIOM)).build();
SnomedConceptDocument parentConcept = concept().build();
SnomedRefSetMemberIndexEntry member = createOwlAxiom(concept.getId(), "").build();
indexRevision(MAIN, concept, parentConcept, member);
statedChangedConceptIds.add(Long.parseLong(concept.getId()));
statedChangedConceptIds.add(Long.parseLong(parentConcept.getId()));
// update axiom
stageChange(member, SnomedRefSetMemberIndexEntry.builder(member).owlExpression(String.format("SubClassOf(:%s :%s)", concept.getId(), parentConcept.getId())).build());
final ConceptChangeProcessor processor = process();
assertEquals(1, processor.getChangedMappings().size());
final SnomedConceptDocument expected = docWithDefaults(concept).statedParents(Long.parseLong(parentConcept.getId())).statedAncestors(IComponent.ROOT_IDL).activeMemberOf(Collections.singleton(Concepts.REFSET_OWL_AXIOM)).memberOf(Collections.singleton(Concepts.REFSET_OWL_AXIOM)).build();
final Revision actual = Iterables.getOnlyElement(processor.getChangedMappings().values()).getNewRevision();
assertDocEquals(expected, actual);
assertEquals(0, processor.getNewMappings().size());
assertEquals(0, processor.getDeletions().size());
}
Aggregations