Copyright ©
Mindbreeze GmbH, A-4020 Linz, 2024.
All rights reserved. All hardware and software names used are trade names and/or trademarks of the respective manufacturers.
These documents are strictly confidential. The transmission and presentation of these documents alone do not create any rights to our software, to our services and service results or to any other protected rights.
The passing on, publication or duplication is not permitted.
For reasons of simpler readability, gender-specific differentiation, e.g. users, is omitted. In the interest of equal treatment, the corresponding terms apply to both genders.
The Query Expression Transformer provides the functionality to transform Mindbreeze query requests arbitrarily. The functionality is provided by creating a plugin using the Mindbreeze Software Development Toolkit. The SDK generates a sample plugin that can be customized.
To build and create a plugin with the Mindbreeze Software Development Toolkit, the following software components are required:
To create a plugin project for a Query Expression Transformer plugin, the creation script must be called with the following parameters:
mesjavaplugin.<sh|bat> <Plugin Type> <Name> <Base Package>
Mindbreeze Software Development Toolkit creates a plugin project that is available under the specified name in the current directory.
A query like:
Poster Cat DIN A4
Transformed to:
(Poster Cat DIN A4) OR (width:297 AND height:210)
Below you can see an example search where an additional document is found by this query transformation.
To transform the request the method, transform must be implemented.
This example is included in the generated code of the SDK and transforms the incoming query expression transformation request. It should be noted that the transformed query expression must finally be forwarded as a query expression transformation response.
/*
* This inherited method is the entry point for transforming queries.
* */
@Override
public void transform(com.google.protobuf.RpcController rpcController,
QueryExprTransformationRequest request,
com.google.protobuf.RpcCallback<QueryExprTransformationResponse> done) {
try {
QueryExpr transformedQueryExpr = transformQueryExpr(request.getQueryExpr()); //transform the query
//build response with transformed query
QueryExprTransformationResponse.Builder responseBuilder = QueryExprTransformationResponse.newBuilder();
responseBuilder.setQueryExpr(transformedQueryExpr);
QueryExprTransformationResponse response = responseBuilder.build();
done.run(response);
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
We perform the actual transformation in the transformQueryExpr method. Here you can see that each type of query expression must be processed separately so that the final result is reassembled properly. Query expressions can be nested within each other and can form a deep tree structure. For transforming queries with such a tree structure, all child queries are processed recursively. The relevant code for this is found in the generated example within the transformOnlyFieldsOfMessage method and can also be reused for individual applications with little customization.
/*
* This Query Expression Transformer can only handle expressions of type EXPR_TERMS.
* These are the kind of query that is generated for queries without any formatting like "cat poster din a4"
* Handling for other kinds of query expressions can be added here.
* It is important to always return a valid Query Expression, not doing so can lead to follow-up-errors
* */
QueryExpr transformQueryExpr(QueryExpr expr) {
if (expr.getKind() == Kind.EXPR_TERMS) {
return transformQueryExprTerms(expr);
}
//recursively iterate through child elements, visit each child element and call transformQueryExpr method again for child query expressions
return (QueryExpr) transformOnlyFieldsOfMessage(expr);
}
In the implementation of transformQueryExprTerms from the generated example, you can see how the original query expression is first searched and manipulated. You can see more examples of creating new query expressions by looking at the unit tests.
/*
* Each kind of Query Expression will need to be handled slightly differently in order to transform the query appropriately.
* This method contains logic to look for "din" and "a4" in the expression terms and perform the corresponding
* transformation if the strings exist in the query.
*/
QueryExpr transformQueryExprTerms(QueryExpr originalExpr) {
if (originalExpr.getKind() != Kind.EXPR_TERMS) {
throw new IllegalArgumentException("Expected kind to be \"EXPR_TERMS\" but was \"" + originalExpr.getKind() + "\"");
}
if (originalExpr.getTermsExpr() == null) {
return originalExpr;
}
List<QueryExpr.Terms.Element> originalTerms = originalExpr.getTermsExpr().getElementList();
String foundDinMarker = getDinMarkerIfInTerms(originalTerms);
//don't transform if the text markers are not found
if (foundDinMarker == null) {
return originalExpr;
}
//build the new query
QueryExpr heightMetadataSearchExpr = QueryExprHelper.labeled(HEIGHT_METADATA_NAME, QueryExprHelper.term(dinStandardToHeightMm.get(foundDinMarker)));
QueryExpr widthMetadataSearchExpr = QueryExprHelper.labeled(WIDTH_METADATA_NAME, QueryExprHelper.term(dinStandardToWidthMm.get(foundDinMarker)));
// In this example, we use 'OR' for the outside of the query to find additional results, which match the metadata
// query while also including all results from the original query
QueryExpr.Builder transformedQuery =
QueryExprHelper.or(
QueryExprHelper.terms(originalTerms),
QueryExprHelper.and(
heightMetadataSearchExpr,
widthMetadataSearchExpr))
.toBuilder();
//always pass on the original unparsed expression
copyOriginalUnparsedExpr(originalExpr, transformedQuery);
return transformedQuery.build();
}