Custom Match Algorithms
Adding custom algorithms or enhanced comparison between values is quite simple using the default match engine in SanteDB. If extending the blocking algorithm, you should implement:
IQueryFilterExtension - Which registers your extended algorithm on the HDSI query interface
IIDbFilterFunction - Which converts your extended HDSI query operation to SQL
If exposing a custom algorithm for scoring, you must implement either:
IUnaryTransform - Which transforms a single operand into another value for subsequent analysis, or
IBinaryTransform - Which transforms two operands into a single result
Implementing Custom IQueryFilterExtension
An IQueryFilter extension is responsible for exposing your filter algorithm on the HDSI query interface. For example, if we wanted to expose a custom query extension for the length of a string.
The primary responsibilities of an IQueryFilterExpression are:
Reserve a name (in this case length_difference) for use on the HDSI interfaces
Compose the parsed expression into a method call and comparison in a LINQ expression tree
Expose the method information to the LINQ composer so it may transform to/from HDSI / LINQ.
This particular filter expression uses an extension method to compose on LINQ, in this case our extension method is defined as:
When the HDSI query engine encounters:
Your filter expression composition method will be invoked and should result in a LINQ expression of:
Implementing Custom IDbFilterFunction
The IQueryFilterExpression is responsible for taking wire-level HTTP queries and constructing LINQ expressions. This is useful for in-memory objects, however to expose the filter expression to a database, a IDbFilterFunction from the ORM Lite library needs to be implemented.
Continuing our example above, a PostgreSQL implementation of length_difference would be:
Implementing Custom IDataTransform for Scoring
If we wanted to use or expose our extended algorithm to the scoring engine as a string transform, we can implement an IDataTransform interface. For example, if we wanted to allow users to configure a scoring attribute:
We would implement an IBinaryDataTransformer as :
In the configuration above, the matching engine would:
Extract the
name.component.value
of record A and record BResolve length_difference to our implementation of IBinaryDataTransformer
Call the
Apply()
method of our transformerPass the result to the next transform or compare it with the assertion provided (in this case the result is less than 2).
Last updated