use of com.b2international.index.query.Expressions.ExpressionBuilder in project snow-owl by b2ihealthcare.
the class RevisionBranchRef method toRevisionFilter.
public Expression toRevisionFilter() {
if (isEmpty()) {
return Expressions.matchNone();
}
final ExpressionBuilder query = Expressions.builder();
final ExpressionBuilder created = Expressions.builder();
for (RevisionSegment segment : segments) {
created.should(segment.toRangeExpression(Revision.Fields.CREATED));
query.mustNot(segment.toRangeExpression(Revision.Fields.REVISED));
}
return query.filter(created.build()).build();
}
use of com.b2international.index.query.Expressions.ExpressionBuilder in project snow-owl by b2ihealthcare.
the class FhirResourceSearchRequest method doExecute.
@Override
protected final Bundle doExecute(RepositoryContext context) throws IOException {
// apply proper field selection
List<String> fields = replaceFieldsToLoad(fields());
// prepare filters
final ExpressionBuilder resourcesQuery = Expressions.builder().filter(ResourceDocument.Expressions.resourceType(getResourceType()));
// resource and version doc has id field
addIdFilter(resourcesQuery, ids -> Expressions.builder().should(ResourceDocument.Expressions.ids(ids)).should(ResourceDocument.Expressions.urls(ids)).build());
// apply _name filter to the id fields, we use the same value for both id and name
addFilter(resourcesQuery, OptionKey.NAME, String.class, ResourceDocument.Expressions::ids);
addFilter(resourcesQuery, OptionKey.URL, String.class, ResourceDocument.Expressions::urls);
addFilter(resourcesQuery, OptionKey.VERSION, String.class, VersionDocument.Expressions::versions);
if (containsKey(OptionKey.TITLE)) {
resourcesQuery.must(ResourceDocument.Expressions.defaultTitleDisjunctionQuery(TermFilter.defaultTermMatch(getString(OptionKey.TITLE))));
}
Hits<ResourceFragment> internalResources = context.service(RevisionSearcher.class).search(Query.select(ResourceFragment.class).from(ResourceDocument.class, VersionDocument.class).fields(fields).where(resourcesQuery.build()).searchAfter(searchAfter()).limit(limit()).sortBy(querySortBy(context)).build());
// in case of version fragments, extract their CodeSystem only information from the latest CodeSystem document (no need to represent older data there)
fillResourceOnlyProperties(context, internalResources, fields);
return prepareBundle().entry(internalResources.stream().map(codeSystem -> toFhirResourceEntry(context, codeSystem)).collect(Collectors.toList())).total(internalResources.getTotal()).build();
}
use of com.b2international.index.query.Expressions.ExpressionBuilder in project snow-owl by b2ihealthcare.
the class SnomedRelationshipSearchRequest method prepareQuery.
@Override
protected Expression prepareQuery(BranchContext context) {
final ExpressionBuilder queryBuilder = Expressions.builder();
addActiveClause(queryBuilder);
addReleasedClause(queryBuilder);
addIdFilter(queryBuilder, RevisionDocument.Expressions::ids);
addEclFilter(context, queryBuilder, SnomedSearchRequest.OptionKey.MODULE, SnomedDocument.Expressions::modules);
addNamespaceFilter(queryBuilder);
addNamespaceConceptIdFilter(context, queryBuilder);
addEffectiveTimeClause(queryBuilder);
addActiveMemberOfClause(context, queryBuilder);
addMemberOfClause(context, queryBuilder);
addEclFilter(context, queryBuilder, OptionKey.SOURCE, SnomedRelationshipIndexEntry.Expressions::sourceIds);
addEclFilter(context, queryBuilder, OptionKey.TYPE, SnomedRelationshipIndexEntry.Expressions::typeIds);
addEclFilter(context, queryBuilder, OptionKey.DESTINATION, SnomedRelationshipIndexEntry.Expressions::destinationIds);
addEclFilter(context, queryBuilder, OptionKey.CHARACTERISTIC_TYPE, SnomedRelationshipIndexEntry.Expressions::characteristicTypeIds);
addEclFilter(context, queryBuilder, OptionKey.MODIFIER, SnomedRelationshipIndexEntry.Expressions::modifierIds);
if (containsKey(OptionKey.GROUP_MIN) || containsKey(OptionKey.GROUP_MAX)) {
final int from = containsKey(OptionKey.GROUP_MIN) ? get(OptionKey.GROUP_MIN, Integer.class) : 0;
final int to = containsKey(OptionKey.GROUP_MAX) ? get(OptionKey.GROUP_MAX, Integer.class) : Integer.MAX_VALUE;
queryBuilder.filter(relationshipGroup(from, to));
}
if (containsKey(OptionKey.UNION_GROUP)) {
queryBuilder.filter(unionGroup(get(OptionKey.UNION_GROUP, Integer.class)));
}
if (containsKey(OptionKey.HAS_DESTINATION_ID)) {
// No need to check the value for the option key here, as it can only be set to "true" in the builder
queryBuilder.filter(hasDestinationId());
}
if (containsKey(OptionKey.VALUE_TYPE)) {
final Collection<RelationshipValueType> valueTypes = getCollection(OptionKey.VALUE_TYPE, RelationshipValueType.class);
queryBuilder.filter(valueTypes(valueTypes));
}
if (containsKey(OptionKey.VALUE)) {
final SearchResourceRequest.Operator op = get(OptionKey.OPERATOR, SearchResourceRequest.Operator.class);
final Collection<RelationshipValue> values = getCollection(OptionKey.VALUE, RelationshipValue.class);
switch(op) {
case EQUALS:
queryBuilder.filter(values(values));
break;
case NOT_EQUALS:
queryBuilder.mustNot(values(values));
break;
case LESS_THAN:
checkRangeValue(values);
queryBuilder.filter(valueLessThan(Iterables.getOnlyElement(values), false));
break;
case LESS_THAN_EQUALS:
checkRangeValue(values);
queryBuilder.filter(valueLessThan(Iterables.getOnlyElement(values), true));
break;
case GREATER_THAN:
checkRangeValue(values);
queryBuilder.filter(valueGreaterThan(Iterables.getOnlyElement(values), false));
break;
case GREATER_THAN_EQUALS:
checkRangeValue(values);
queryBuilder.filter(valueGreaterThan(Iterables.getOnlyElement(values), true));
break;
default:
throw new NotImplementedException("Unsupported concrete value operator %s", op);
}
}
return queryBuilder.build();
}
use of com.b2international.index.query.Expressions.ExpressionBuilder in project snow-owl by b2ihealthcare.
the class BaseResourceSearchRequest method addTitleFilter.
protected final ExpressionBuilder addTitleFilter(ExpressionBuilder queryBuilder) {
if (!containsKey(OptionKey.TITLE)) {
return queryBuilder;
}
final TermFilter termFilter = get(OptionKey.TITLE, TermFilter.class);
final ExpressionBuilder expressionBuilder = Expressions.builder();
if (termFilter.isFuzzy()) {
expressionBuilder.should(ResourceDocument.Expressions.titleFuzzy(termFilter.getTerm()));
} else if (termFilter.isExact()) {
expressionBuilder.should(ResourceDocument.Expressions.matchTitleExact(termFilter.getTerm(), termFilter.isCaseSensitive()));
} else if (termFilter.isParsed()) {
expressionBuilder.should(ResourceDocument.Expressions.parsedTitle(termFilter.getTerm()));
} else if (termFilter.isAnyMatch()) {
expressionBuilder.should(ResourceDocument.Expressions.minShouldMatchTermDisjunctionQuery(termFilter));
} else {
expressionBuilder.should(ResourceDocument.Expressions.defaultTitleDisjunctionQuery(termFilter));
}
expressionBuilder.should(Expressions.boost(ResourceDocument.Expressions.id(termFilter.getTerm()), 1000.0f));
return queryBuilder.must(expressionBuilder.build());
}
use of com.b2international.index.query.Expressions.ExpressionBuilder in project snow-owl by b2ihealthcare.
the class BaseResourceSearchRequest method addSecurityFilter.
/**
* Configures security filters to allow access to certain resources only. This method is no-op if the given {@link ServiceProvider context}'s {@link User} is an administrator or has read access to everything.
*
* @param context - the context where user information will be extracted
* @param queryBuilder - the query builder to append the clauses to
*/
protected final void addSecurityFilter(ServiceProvider context, ExpressionBuilder queryBuilder) {
final User user = context.service(User.class);
if (user.isAdministrator() || user.hasPermission(Permission.requireAll(Permission.OPERATION_BROWSE, Permission.ALL))) {
return;
}
// extract read permissions
final List<Permission> readPermissions = user.getPermissions().stream().filter(p -> Permission.ALL.equals(p.getOperation()) || Permission.OPERATION_BROWSE.equals(p.getOperation())).collect(Collectors.toList());
final Set<String> exactResourceIds = readPermissions.stream().flatMap(p -> p.getResources().stream()).filter(resource -> !resource.endsWith("*")).collect(Collectors.toSet());
final Set<String> resourceIdPrefixes = readPermissions.stream().flatMap(p -> p.getResources().stream()).filter(resource -> resource.endsWith("*")).map(resource -> resource.substring(0, resource.length() - 1)).collect(Collectors.toSet());
if (!exactResourceIds.isEmpty() || !resourceIdPrefixes.isEmpty()) {
context.log().info("Restricting user '{}' to resources exact: '{}', prefix: '{}'.", user.getUsername(), ImmutableSortedSet.copyOf(exactResourceIds), ImmutableSortedSet.copyOf(resourceIdPrefixes));
ExpressionBuilder bool = Expressions.builder();
// the permissions give access to either
if (!exactResourceIds.isEmpty()) {
// explicit IDs
bool.should(ResourceDocument.Expressions.ids(exactResourceIds));
// or the permitted resources are bundles which give access to all resources within it (recursively)
bool.should(ResourceDocument.Expressions.bundleIds(exactResourceIds));
bool.should(ResourceDocument.Expressions.bundleAncestorIds(exactResourceIds));
}
if (!resourceIdPrefixes.isEmpty()) {
// partial IDs, prefixes
bool.should(ResourceDocument.Expressions.idPrefixes(resourceIdPrefixes));
// or the permitted resources are bundle ID prefixes which give access to all resources within it (recursively)
bool.should(ResourceDocument.Expressions.bundleIdPrefixes(resourceIdPrefixes));
bool.should(ResourceDocument.Expressions.bundleAncestorIdPrefixes(resourceIdPrefixes));
}
queryBuilder.filter(bool.build());
} else {
throw new NoResultException();
}
}
Aggregations