Move search query loading options to a better place in the search query DSL

Description

Right now, if you want to set loading options when building a search query, it has to be the very first thing you do:

SearchResult<Document> result = searchSession.search( Book.class, Video.class ) .fetchSize( 100 ) .asProjection( ... ) .predicate( f -> f.match().onField( "title" ) .matching( "robot" ) ) .fetch();

As you can see, it's quite weird when specifying the result type explicitly.
Ideally we'd want this:

SearchResult<Document> result = searchSession.search( Book.class, Video.class ) .asProjection( ... ) .fetchSize( 100 ) .predicate( f -> f.match().onField( "title" ) .matching( "robot" ) ) .fetch();

... but because we want to support backend-specific options in .asProjection(), it's not possible (at least not unless we define one API for every mapper/backend combination).

Maybe we could expose something like this?

SearchResult<Document> result = searchSession.search( Book.class, Video.class ) .asProjection( ... ) .loading( c -> c.fetchSize( 100 ) ) .predicate( f -> f.match().onField( "title" ) .matching( "robot" ) ) .fetch();

Note this could make much more sense when combined with HSEARCH-3628, where we need to expose per-type options. We'd end up with this:

SearchResult<Document> result = searchSession.search( Book.class, Video.class ) .asProjection( ... ) .loading( Book.class, c -> c.fetchSize( 100 ) ) .loading( Video.class, c -> c.fetchSize( 200 ).fetchGraph( ... ) ) .predicate( f -> f.match().onField( "title" ) .matching( "robot" ) ) .fetch();

Or, more probably (to be truly mapper-agnostic, and avoid the dubious assumption that mapped types are Java types):

SearchResult<Document> result = searchSession.search( Book.class, Video.class ) .asProjection( ... ) .loading( c -> { c.forType( Book.class ).fetchSize( 100 ); c.forType( Video.class ).fetchSize( 100 ); } ) .predicate( f -> f.match().onField( "title" ) .matching( "robot" ) ) .fetch();

We may want to also allow an optional, non-lambda syntax:

SearchScope<Document> scope = searchSession.search( Book.class, Video.class ) SearchLoadingOptions loadingOptions = scope.loadingOptions().composite() .add( scope.loadingOptions().forType( Book.class ).fetchSize( 100 ).toOptions() ) .add( scope.loadingOptions().forType( Book.class ).fetchSize( 100 ).toOptions() ) .toOptions(); SearchPredicate predicate = scope.predicate()..match().onField( "title" ) .matching( "robot" ) .toPredicate(); SearchResult<Document> result = searchSession.search( Book.class, Video.class ) .asProjection( ... ) .loading( loadingOptions ) .predicate( predicate ) .fetch();

Activity

Show:
Fixed

Details

Assignee

Reporter

Sprint

Fix versions

Priority

Created June 28, 2019 at 3:54 PM
Updated January 22, 2020 at 2:18 PM
Resolved January 14, 2020 at 3:24 PM

Flag notifications