use of com.b2international.snowowl.core.events.util.Promise in project snow-owl by b2ihealthcare.
the class EclExpression method resolveToGroupedOnly.
private Promise<Multimap<String, Integer>> resolveToGroupedOnly(BranchContext context, Set<String> sourceIds) {
final Set<String> characteristicTypes = isInferred() ? SnomedEclRefinementEvaluator.INFERRED_CHARACTERISTIC_TYPES : SnomedEclRefinementEvaluator.STATED_CHARACTERISTIC_TYPES;
List<Promise<Multimap<String, Integer>>> promises = newArrayListWithCapacity(3);
// search relationships
promises.add(SnomedRequests.prepareSearchRelationship().all().filterByActive(true).filterByCharacteristicTypes(characteristicTypes).filterBySources(sourceIds).filterByGroup(1, Integer.MAX_VALUE).setEclExpressionForm(expressionForm).setFields(SnomedRelationshipIndexEntry.Fields.ID, SnomedRelationshipIndexEntry.Fields.SOURCE_ID, SnomedRelationshipIndexEntry.Fields.RELATIONSHIP_GROUP).build(context.service(ResourceURI.class)).execute(context.service(IEventBus.class)).then(new Function<SnomedRelationships, Multimap<String, Integer>>() {
@Override
public Multimap<String, Integer> apply(SnomedRelationships input) {
final Multimap<String, SnomedRelationship> relationshipsBySource = Multimaps.index(input, SnomedRelationship::getSourceId);
final Multimap<String, Integer> groupsByRelationshipId = Multimaps.transformValues(relationshipsBySource, SnomedRelationship::getRelationshipGroup);
return ImmutableSetMultimap.copyOf(groupsByRelationshipId);
}
}));
// search concrete domain members
if (context.service(SnomedCoreConfiguration.class).isConcreteDomainSupported()) {
final Options propFilter = Options.builder().put(SnomedRf2Headers.FIELD_CHARACTERISTIC_TYPE_ID, characteristicTypes).put(SearchResourceRequest.operator(SnomedRf2Headers.FIELD_RELATIONSHIP_GROUP), SearchResourceRequest.Operator.NOT_EQUALS).put(SnomedRf2Headers.FIELD_RELATIONSHIP_GROUP, 0).build();
promises.add(SnomedRequests.prepareSearchMember().all().filterByActive(true).filterByReferencedComponent(sourceIds).filterByRefSetType(SnomedRefSetType.CONCRETE_DATA_TYPE).filterByProps(propFilter).setEclExpressionForm(expressionForm).build(context.service(ResourceURI.class)).execute(context.service(IEventBus.class)).then(members -> {
final Multimap<String, SnomedReferenceSetMember> relationshipsBySource = Multimaps.index(members, m -> m.getReferencedComponent().getId());
return Multimaps.transformValues(relationshipsBySource, m -> (Integer) m.getProperties().get(SnomedRf2Headers.FIELD_RELATIONSHIP_GROUP));
}));
} else {
promises.add(Promise.immediate(ImmutableSetMultimap.of()));
}
// search owl axiom members
if (isStated()) {
ImmutableSetMultimap.Builder<String, Integer> groupedAxioms = ImmutableSetMultimap.builder();
SnomedEclRefinementEvaluator.evalAxiomStatements(context, true, sourceIds, null, null).forEach(property -> groupedAxioms.put(property.getObjectId(), property.getGroup()));
promises.add(Promise.immediate(groupedAxioms.build()));
} else {
promises.add(Promise.immediate(ImmutableSetMultimap.of()));
}
return Promise.all(promises).then(statements -> {
Multimap<String, Integer> relationshipStatements = (Multimap<String, Integer>) statements.get(0);
Multimap<String, Integer> concreteDomainStatements = (Multimap<String, Integer>) statements.get(1);
Multimap<String, Integer> axiomStatements = (Multimap<String, Integer>) statements.get(2);
return ImmutableSetMultimap.<String, Integer>builder().putAll(relationshipStatements).putAll(concreteDomainStatements).putAll(axiomStatements).build();
});
}
use of com.b2international.snowowl.core.events.util.Promise in project snow-owl by b2ihealthcare.
the class SnomedEclEvaluationRequest method eval.
/**
* Handles (possibly) filtered expression constraints by evaluating them along
* with the primary ECL expression, and adding the resulting query expressions as
* extra required clauses.
*
* @param context
* @param filtered
* @return
*/
protected Promise<Expression> eval(BranchContext context, final FilteredExpressionConstraint filtered) {
final ExpressionConstraint constraint = filtered.getConstraint();
final FilterConstraint filterConstraint = filtered.getFilter();
final Domain filterDomain = Ecl.getDomain(filterConstraint);
final Filter filter = filterConstraint.getFilter();
final Promise<Expression> evaluatedConstraint = evaluate(context, constraint);
Promise<Expression> evaluatedFilter = evaluate(context, filter);
if (Domain.DESCRIPTION.equals(filterDomain)) {
// Find concepts that match the description expression, then use the resulting concept IDs as the expression
evaluatedFilter = evaluatedFilter.then(ex -> executeDescriptionSearch(context, ex));
}
if (isAnyExpression(constraint)) {
// No need to combine "match all" with the filter query expression, return it directly
return evaluatedFilter;
}
return Promise.all(evaluatedConstraint, evaluatedFilter).then(results -> {
final Expressions.ExpressionBuilder builder = Expressions.builder();
results.forEach(f -> builder.filter((Expression) f));
return builder.build();
});
}
use of com.b2international.snowowl.core.events.util.Promise in project snow-owl by b2ihealthcare.
the class SnomedEclRefinementEvaluator method evalStatements.
/**
* Executes a SNOMED CT Relationship search request using the given source, type, destination filters.
* If the groupedRelationshipsOnly boolean flag is <code>true</code>, then the search will match relationships that are grouped (their groupId is greater than or equals to <code>1</code>).
* @param context - the context where the search should happen
* @param sourceFilter - filter for relationship sources
* @param typeFilter - filter for relationship types
* @param destinationFilter - filter for relationship destinations
* @param groupedRelationshipsOnly - whether the search should consider grouped relationships only or not
* @return a {@link Promise} of {@link Collection} of {@link Property} objects that match the criteria
* @see SnomedRelationshipSearchRequestBuilder
*/
/*package*/
static Promise<Collection<Property>> evalStatements(final BranchContext context, final Collection<String> sourceFilter, final Collection<String> typeFilter, final Collection<String> destinationFilter, final boolean groupedRelationshipsOnly, final String expressionForm) {
final ImmutableList.Builder<String> fieldsToLoad = ImmutableList.builder();
fieldsToLoad.add(SnomedDocument.Fields.ID, SOURCE_ID, TYPE_ID, DESTINATION_ID);
if (groupedRelationshipsOnly) {
fieldsToLoad.add(RELATIONSHIP_GROUP);
}
SnomedRelationshipSearchRequestBuilder searchRelationships = SnomedRequests.prepareSearchRelationship().filterByActive(true).filterBySources(sourceFilter).filterByTypes(typeFilter).filterByDestinations(destinationFilter).filterByCharacteristicTypes(getCharacteristicTypes(expressionForm)).setEclExpressionForm(expressionForm).setFields(fieldsToLoad.build()).setLimit(context.service(RepositoryConfiguration.class).getIndexConfiguration().getResultWindow());
// if a grouping refinement, then filter relationships with group >= 1
if (groupedRelationshipsOnly) {
searchRelationships.filterByGroup(1, Integer.MAX_VALUE);
}
Promise<Collection<Property>> relationshipSearch = searchRelationships.transformAsync(context, req -> req.build(context.service(ResourceURI.class)), relationships -> relationships.stream().map(r -> new Property(r.getSourceId(), r.getTypeId(), r.getDestinationId(), r.getRelationshipGroup())));
if (Trees.STATED_FORM.equals(expressionForm)) {
final Set<Property> axiomStatements = evalAxiomStatements(context, groupedRelationshipsOnly, sourceFilter, typeFilter, destinationFilter);
return relationshipSearch.then(relationshipStatements -> ImmutableSet.<Property>builder().addAll(relationshipStatements).addAll(axiomStatements).build());
} else {
return relationshipSearch;
}
}
use of com.b2international.snowowl.core.events.util.Promise in project snow-owl by b2ihealthcare.
the class SnomedEclRefinementEvaluator method evalAxiomsWithValue.
private Promise<Collection<Property>> evalAxiomsWithValue(BranchContext context, Set<String> focusConceptIds, Collection<String> typeIds, RelationshipValue value, SearchResourceRequest.Operator operator) {
// search existing axioms defined for the given set of conceptIds
ExpressionBuilder axiomFilter = Expressions.builder();
if (typeIds != null) {
axiomFilter.filter(typeIds(typeIds));
}
switch(operator) {
case EQUALS:
axiomFilter.filter(values(List.of(value)));
break;
case GREATER_THAN:
axiomFilter.filter(valueGreaterThan(value, false));
break;
case GREATER_THAN_EQUALS:
axiomFilter.filter(valueGreaterThan(value, true));
break;
case LESS_THAN:
axiomFilter.filter(valueLessThan(value, false));
break;
case LESS_THAN_EQUALS:
axiomFilter.filter(valueLessThan(value, true));
break;
case NOT_EQUALS:
axiomFilter.mustNot(values(List.of(value)));
break;
default:
throw new IllegalStateException("Unexpected operator '" + operator + "'.");
}
ExpressionBuilder activeOwlAxiomMemberQuery = Expressions.builder().filter(active()).filter(Expressions.nestedMatch(SnomedRefSetMemberIndexEntry.Fields.CLASS_AXIOM_RELATIONSHIP, axiomFilter.build()));
if (focusConceptIds != null) {
activeOwlAxiomMemberQuery.filter(SnomedRefSetMemberIndexEntry.Expressions.referencedComponentIds(focusConceptIds));
}
final Query<SnomedRefSetMemberIndexEntry> activeAxiomStatementsQuery = Query.select(SnomedRefSetMemberIndexEntry.class).where(activeOwlAxiomMemberQuery.build()).limit(context.service(RepositoryConfiguration.class).getIndexConfiguration().getResultWindow()).build();
final Set<Property> axiomProperties = newHashSet();
context.service(RevisionSearcher.class).stream(activeAxiomStatementsQuery).forEach(chunk -> {
chunk.stream().filter(owlMember -> !CompareUtils.isEmpty(owlMember.getClassAxiomRelationships())).forEachOrdered(owlMember -> {
owlMember.getClassAxiomRelationships().stream().filter(r -> typeIds == null || typeIds.contains(r.getTypeId())).filter(r -> r.getValueAsObject().matches(operator, value)).map(r -> new Property(owlMember.getReferencedComponentId(), r.getTypeId(), r.getValueAsObject().toObject(), r.getRelationshipGroup())).forEachOrdered(axiomProperties::add);
});
});
return Promise.immediate(axiomProperties);
}
use of com.b2international.snowowl.core.events.util.Promise in project snow-owl by b2ihealthcare.
the class SnomedEclRefinementEvaluator method evalRefinement.
/**
* Evaluates an {@link AttributeConstraint} refinement on the given focusConceptId set on the given {@link BranchContext}.
* Grouped parameter can
*/
private Promise<Collection<Property>> evalRefinement(final BranchContext context, final AttributeConstraint refinement, final boolean grouped, final Set<String> focusConceptIds) {
final Comparison comparison = refinement.getComparison();
final Collection<String> typeConceptFilter = evalToConceptIds(context, refinement.getAttribute(), expressionForm).getSync(1, TimeUnit.MINUTES);
if (comparison instanceof AttributeComparison) {
// resolve non-* focusConcept ECLs to IDs, so we can filter relationships by source/destination
// filterByType and filterByDestination accepts ECL expressions as well, so serialize them into ECL and pass as String when required
// if reversed refinement, then we are interested in the destinationIds otherwise we need the sourceIds
final Collection<String> destinationConceptFilter = evalToConceptIds(context, ((AttributeComparison) comparison).getValue(), expressionForm).getSync(1, TimeUnit.MINUTES);
final Collection<String> focusConceptFilter = refinement.isReversed() ? destinationConceptFilter : focusConceptIds;
final Collection<String> valueConceptFilter = refinement.isReversed() ? focusConceptIds : destinationConceptFilter;
return evalStatements(context, focusConceptFilter, typeConceptFilter, valueConceptFilter, grouped, expressionForm);
} else if (comparison instanceof DataTypeComparison) {
if (refinement.isReversed()) {
throw new BadRequestException("Reversed flag is not supported in data type based comparison (string/numeric)");
} else {
final Promise<Collection<Property>> statementsWithValue = evalStatementsWithValue(context, focusConceptIds, typeConceptFilter, (DataTypeComparison) comparison);
final Promise<Collection<Property>> members = evalMembers(context, focusConceptIds, typeConceptFilter, (DataTypeComparison) comparison);
return Promise.all(statementsWithValue, members).then(results -> {
final Collection<Property> s = (Collection<Property>) results.get(0);
final Collection<Property> m = (Collection<Property>) results.get(1);
return FluentIterable.concat(s, m).toSet();
});
}
} else {
return SnomedEclEvaluationRequest.throwUnsupported(comparison);
}
}
Aggregations