We're updating the issue view to help you get more done. 

Reduce the verbosity of the predicate/projection/sort DSLs and index schema DSL

Description

The DSLs in Search 6 are relatively verbose, even when using the lambda syntax:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager( entityManager ); FullTextQuery<MyProjectionBean> query = fullTextEntityManager.search( Book.class ).query() .asProjection( f -> f.composite( MyProjectionBean::new, f.field( "id_stored", Long.class ) f.field( "title", String.class ) ).toProjection() ) .predicate( f -> f.match() .onFields( "title", "authors.name" ) .matching( "Refactoring: Improving the Design of Existing Code" ) .toPredicate() ) .sort( f -> f.byField( "title" ).asc() .then().byField( "subtitle" ).asc() .toSort() ) .build(); List<MyProjectionBean> result = query.getResultList();

We could try to improve on that.
One idea would be to remove the need to call the toPredicate, toProjection, toSort}}‌and {{toIndexFieldType methods even at the top level:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager( entityManager ); FullTextQuery<MyProjectionBean> query = fullTextEntityManager.search( Book.class ).query() .asProjection( f -> f.composite( MyProjectionBean::new, f.field( "id_stored", Long.class ) f.field( "title", String.class ) ) ) .predicate( f -> f.match() .onFields( "title", "authors.name" ) .matching( "Refactoring: Improving the Design of Existing Code" ) ) .sort( f -> f.byField( "title" ).asc() .then().byField( "subtitle" ).asc() ) .build(); List<MyProjectionBean> result = query.getResultList();

That would, however, remove the ability to return a cached SearchPredicate/SearchProjection/SearchSort object from the lambda: the lambda would be expected to return a Search(Predicate/Projection/Sort)TerminalContext.

Maybe we should add a method to the DSL to convert a SearchPredicate/SearchProjection/SearchSort to a Search(Predicate/Projection/Sort)TerminalContext? Something like f.from(searchPredicate)? If we do that, it could make sense to change the naming around SearchPredicate/SearchProjection/SearchSort: we could make it more obvious that these are mainly for re-use, and are not really necessary if you don't cache them. Maybe rename them to ReusablePredicate, or something similar?

Note that the index schema DSL also suffers from unnecessary verbosity:

1 2 this.accessor = root.field( "geoPoint_1", f -> f.asGeoPoint().toIndexFieldType() ) .createAccessor();

With the same solution as above, we would get to something like this:

1 2 this.accessor = root.field( "geoPoint_1", f -> f.asGeoPoint() ) .createAccessor();

We could improve this even further by removing the createAccessor call:

1 this.accessor = root.field( "geoPoint_1", f -> f.asGeoPoint() );

… but then there would be an inconsistency with object fields, where the‌{{createAccessor}} call is actually necessary, because the user needs a builder to add sub-fields to the object field:

1 2 3 4 IndexSchemaObjectField objectField = context.getIndexSchemaElement().objectField( "object" ); this.objectFieldAccessor = objectField.createAccessor(); this.subField1Accessor = objectField.field( "subField1", f -> f.asString() ); this.subField2Accessor = objectField.field( "subField2", f -> f.asInteger() );

Maybe we should just acknowledge this inconsistency by considering the objectField object above as a builder? Then it would make more sense: when you use a builder, you expect a final call. Something like this maybe:

1 2 3 4 IndexSchemaObjectField objectFieldBuilder = context.getIndexSchemaElement().objectFieldBuilder( "object" ); this.subField1Accessor = objectFieldBuilder.field( "subField1", f -> f.asString() ); this.subField2Accessor = objectFieldBuilder.field( "subField2", f -> f.asInteger() ); this.objectFieldAccessor = objectFieldBuilder.build(); // or ".createAccessor()"? It seems odd with a builder...

Also to be taken into account: we may want one day to add "sub-fields" to non-object fields; see HSEARCH-3465.

Environment

None

Status

Assignee

Yoann Rodière

Reporter

Yoann Rodière

Labels

None

Suitable for new contributors

None

Feedback Requested

None

Components

Fix versions

Priority

Major