[JIRA] (HSEARCH-4827) Only allow nesting-aware projections within `object` projections
by Yoann Rodière (JIRA)
Yoann Rodière ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=557058%... ) *created* an issue
Hibernate Search ( https://hibernate.atlassian.net/browse/HSEARCH?atlOrigin=eyJpIjoiZjZmZTE4... ) / Task ( https://hibernate.atlassian.net/browse/HSEARCH-4827?atlOrigin=eyJpIjoiZjZ... ) HSEARCH-4827 ( https://hibernate.atlassian.net/browse/HSEARCH-4827?atlOrigin=eyJpIjoiZjZ... ) Only allow nesting-aware projections within `object` projections ( https://hibernate.atlassian.net/browse/HSEARCH-4827?atlOrigin=eyJpIjoiZjZ... )
Issue Type: Task Assignee: Unassigned Components: backend-elasticsearch, backend-lucene, engine Created: 28/Mar/2023 00:37 AM Fix Versions: 6.2-backlog Priority: Major Reporter: Yoann Rodière ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=557058%... )
-------
Problem
-------
Currently we allow projections that are not aware of nesting within object projections, which apply nesting. So this is allowed:
List<MyBookProjection> hits = searchSession.search( Book.class )
.select( f -> f.composite()
.from(
f.field( "title", String.class ),
f.object( "authors" )
.from(
f.id(), // ????
f.field( "authors.firstName", String.class ),
f.field( "authors.lastName", String.class )
)
.as( MyBookProjection.Author::new )
.multi()
)
.as( MyBookProjection::new ) )
.where( f -> f.matchAll() )
.fetchHits( 20 );
This is dodgy, because it seems like the ID that will end up in the author projections is the author ID, but it will in fact be the book ID. (And BTW, we just don’t support using.id() for author ID projections at the moment, people are expected to use f.field("authors.id") )
Other projections, such as explanations, source hits, loaded entity, etc., will give similarly confusing results, where the same (intrinsically root-related) value is simply repeated for each author.
--------
Solution
--------
We should apply restrictions regarding the context in which projections can be used: if the projection cannot adapt to the nesting context, then it should throw an exception upon calling.request and explain that this projection can only be used in the root context.
*If* we feel that it’s useful to allow it, but only when the user is explicitly requesting it, we can expose something like the (currently SPI) rootContext method: org.hibernate.search.engine.search.projection.spi.SearchProjectionBuilderFactory#rootContext. We’d end up with something like this:
List<MyBookProjection> hits = searchSession.search( Book.class )
.select( f -> f.composite()
.from(
f.field( "title", String.class ),
f.object( "authors" )
.from(
f.fromRoot( f.id() ), // We EXPLICITLY tell HSearch to use the root ID
f.field( "authors.firstName", String.class ),
f.field( "authors.lastName", String.class )
)
.as( MyBookProjection.Author::new )
.multi()
)
.as( MyBookProjection::new ) )
.where( f -> f.matchAll() )
.fetchHits( 20 );
Note there’s a similarity between this fromRoot projection and Elasticsearch's concept of reverse_nested aggregations: https://www.elastic.co/guide/en/elasticsearch/reference/current/search-ag... ( https://www.elastic.co/guide/en/elasticsearch/reference/current/search-ag... ). Maybe we could introduce that kind of things later, but that’s definitely beyond the scope of this issue.
( https://hibernate.atlassian.net/browse/HSEARCH-4827#add-comment?atlOrigin... ) Add Comment ( https://hibernate.atlassian.net/browse/HSEARCH-4827#add-comment?atlOrigin... )
Get Jira notifications on your phone! Download the Jira Cloud app for Android ( https://play.google.com/store/apps/details?id=com.atlassian.android.jira.... ) or iOS ( https://itunes.apple.com/app/apple-store/id1006972087?pt=696495&ct=EmailN... ) This message was sent by Atlassian Jira (v1001.0.0-SNAPSHOT#100219- sha1:6a6077b )
3 years