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=Em...
) This message was sent by Atlassian Jira (v1001.0.0-SNAPSHOT#100219- sha1:6a6077b )