Closed
Description
When selecting data from a query (e.g. SELECT id,comment,language,similarity_cosine(embedding,:embedding) AS score FROM comments
) that returns an entity and auxiliary information (such as a score), it makes sense to capture materialize the entity independently from the score
.
While it would be possible to create a dedicated data structure for this projection result, it is much leaner to reuse existing data models and customize the result mapping at the stage where CassandraTemplate
already has access to the Row
.
Something along the lines of:
/**
* Trigger {@code SELECT} query execution by calling one of the terminating methods and return mapped results.
*/
interface TerminatingResults<T> {
<R> TerminatingResults<R> map(QueryResultConverter<? super T, ? extends R> converter);
default Optional<T> first() {
return Optional.ofNullable(firstValue());
}
@Nullable
T firstValue();
// …
The actual converter needs to be tied to the Row
and upstream result produced by a converter:
interface QueryResultConverter<T, R> {
/**
* Returns a function that returns the materialized entity..
*/
@SuppressWarnings("unchecked")
static <T> QueryResultConverter<T, T> entity() {
return (row, result) -> result.get();
}
R mapRow(Row row, ConversionResultSupplier<T> reader);
/**
* A supplier that converts a {@link Row} into {@code T}. Allows for lazy reading of query results.
*/
interface ConversionResultSupplier<T> {
/**
* Obtain the upstream conversion result.
*
* @return the upstream conversion result.
*/
T get();
}
}
Open issues:
- Find a better name for
ConversionResultSupplier
. Supplier
pattern allowsLazy
caching to buffer multiple calls toget
, however, aUpstreamConverter.convert(Row)
might be more explicit