Skip to content

Commit 9023250

Browse files
committed
HSEARCH-4806 Parameterized projection
1 parent 470d438 commit 9023250

File tree

16 files changed

+1325
-790
lines changed

16 files changed

+1325
-790
lines changed

backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/search/projection/impl/ElasticsearchSearchProjectionBuilderFactory.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,15 @@
88

99
import java.util.HashMap;
1010
import java.util.Map;
11+
import java.util.function.Function;
1112
import java.util.function.Supplier;
1213

1314
import org.hibernate.search.backend.elasticsearch.search.common.impl.ElasticsearchSearchIndexScope;
1415
import org.hibernate.search.engine.backend.common.DocumentReference;
16+
import org.hibernate.search.engine.search.common.NamedValues;
1517
import org.hibernate.search.engine.search.common.spi.SearchIndexIdentifierContext;
1618
import org.hibernate.search.engine.search.projection.SearchProjection;
19+
import org.hibernate.search.engine.search.projection.dsl.ProjectionFinalStep;
1720
import org.hibernate.search.engine.search.projection.spi.CompositeProjectionBuilder;
1821
import org.hibernate.search.engine.search.projection.spi.SearchProjectionBuilderFactory;
1922
import org.hibernate.search.util.common.SearchException;
@@ -94,6 +97,12 @@ public <T> SearchProjection<T> byTypeName(Map<String, ? extends SearchProjection
9497
elasticsearchInners );
9598
}
9699

100+
@Override
101+
public <T> SearchProjection<T> withParameters(
102+
Function<? super NamedValues, ? extends ProjectionFinalStep<T>> projectionCreator) {
103+
return new ElasticsearchWithParametersProjection<>( scope, projectionCreator );
104+
}
105+
97106
public SearchProjection<JsonObject> source() {
98107
return new ElasticsearchSourceProjection( scope );
99108
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Hibernate Search, full-text search for your domain model
3+
*
4+
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
5+
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
6+
*/
7+
package org.hibernate.search.backend.elasticsearch.search.projection.impl;
8+
9+
import java.util.function.Function;
10+
11+
import org.hibernate.search.backend.elasticsearch.search.common.impl.ElasticsearchSearchIndexScope;
12+
import org.hibernate.search.engine.search.common.NamedValues;
13+
import org.hibernate.search.engine.search.projection.SearchProjection;
14+
import org.hibernate.search.engine.search.projection.dsl.ProjectionFinalStep;
15+
16+
import com.google.gson.JsonObject;
17+
18+
final class ElasticsearchWithParametersProjection<P>
19+
extends AbstractElasticsearchProjection<P> {
20+
21+
private final ElasticsearchSearchIndexScope<?> scope;
22+
private final Function<? super NamedValues,
23+
? extends ProjectionFinalStep<P>> projectionCreator;
24+
25+
public ElasticsearchWithParametersProjection(ElasticsearchSearchIndexScope<?> scope,
26+
Function<? super NamedValues, ? extends ProjectionFinalStep<P>> projectionCreator) {
27+
super( scope );
28+
this.scope = scope;
29+
this.projectionCreator = projectionCreator;
30+
}
31+
32+
@Override
33+
public String toString() {
34+
return getClass().getSimpleName() + "["
35+
+ "projectionCreator=" + projectionCreator
36+
+ "]";
37+
}
38+
39+
@Override
40+
public Extractor<?, P> request(JsonObject requestBody, ProjectionRequestContext context) {
41+
SearchProjection<P> delegate = projectionCreator.apply( context.queryParameters() )
42+
.toProjection();
43+
return ElasticsearchSearchProjection.from( scope, delegate ).request( requestBody, context );
44+
}
45+
46+
}

backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/projection/impl/LuceneSearchProjectionBuilderFactory.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,16 @@
88

99
import java.util.HashMap;
1010
import java.util.Map;
11+
import java.util.function.Function;
1112
import java.util.function.Supplier;
1213

1314
import org.hibernate.search.backend.lucene.scope.model.impl.LuceneSearchIndexScopeImpl;
1415
import org.hibernate.search.backend.lucene.search.projection.dsl.DocumentTree;
1516
import org.hibernate.search.engine.backend.common.DocumentReference;
17+
import org.hibernate.search.engine.search.common.NamedValues;
1618
import org.hibernate.search.engine.search.common.spi.SearchIndexIdentifierContext;
1719
import org.hibernate.search.engine.search.projection.SearchProjection;
20+
import org.hibernate.search.engine.search.projection.dsl.ProjectionFinalStep;
1821
import org.hibernate.search.engine.search.projection.spi.CompositeProjectionBuilder;
1922
import org.hibernate.search.engine.search.projection.spi.SearchProjectionBuilderFactory;
2023
import org.hibernate.search.util.common.SearchException;
@@ -86,6 +89,12 @@ public <T> SearchProjection<T> byTypeName(Map<String, ? extends SearchProjection
8689
return new LuceneByMappedTypeProjection<>( scope, luceneInners );
8790
}
8891

92+
@Override
93+
public <T> SearchProjection<T> withParameters(
94+
Function<? super NamedValues, ? extends ProjectionFinalStep<T>> projectionCreator) {
95+
return new LuceneWithParametersProjection<>( scope, projectionCreator );
96+
}
97+
8998
public SearchProjection<Document> document() {
9099
return new LuceneDocumentProjection( scope );
91100
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Hibernate Search, full-text search for your domain model
3+
*
4+
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
5+
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
6+
*/
7+
package org.hibernate.search.backend.lucene.search.projection.impl;
8+
9+
import java.util.function.Function;
10+
11+
import org.hibernate.search.backend.lucene.search.common.impl.LuceneSearchIndexScope;
12+
import org.hibernate.search.engine.search.common.NamedValues;
13+
import org.hibernate.search.engine.search.projection.SearchProjection;
14+
import org.hibernate.search.engine.search.projection.dsl.ProjectionFinalStep;
15+
16+
public class LuceneWithParametersProjection<P> extends AbstractLuceneProjection<P> {
17+
18+
private final LuceneSearchIndexScope<?> scope;
19+
private final Function<? super NamedValues,
20+
? extends ProjectionFinalStep<P>> projectionCreator;
21+
22+
public LuceneWithParametersProjection(LuceneSearchIndexScope<?> scope,
23+
Function<? super NamedValues, ? extends ProjectionFinalStep<P>> projectionCreator) {
24+
super( scope );
25+
this.scope = scope;
26+
this.projectionCreator = projectionCreator;
27+
}
28+
29+
@Override
30+
public String toString() {
31+
return getClass().getSimpleName() + "["
32+
+ "projectionCreator=" + projectionCreator
33+
+ "]";
34+
}
35+
36+
@Override
37+
public Extractor<?, P> request(ProjectionRequestContext context) {
38+
SearchProjection<P> delegate = projectionCreator.apply( context.queryParameters() ).toProjection();
39+
40+
return LuceneSearchProjection.from( scope, delegate ).request( context );
41+
}
42+
}

engine/src/main/java/org/hibernate/search/engine/search/projection/definition/ProjectionDefinitionContext.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,4 @@
1616
@Incubating
1717
public interface ProjectionDefinitionContext {
1818

19-
// TODO HSEARCH-4806/HSEARCH-4807 expose parameters here, to be defined in the query, useful in particular for the distance projection.
20-
2119
}

engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/SearchProjectionFactory.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
import org.hibernate.search.engine.backend.common.DocumentReference;
1414
import org.hibernate.search.engine.common.EntityReference;
15+
import org.hibernate.search.engine.search.common.NamedValues;
1516
import org.hibernate.search.engine.search.common.ValueConvert;
1617
import org.hibernate.search.engine.search.projection.SearchProjection;
1718
import org.hibernate.search.engine.spatial.GeoPoint;
@@ -386,6 +387,18 @@ default <P1, P2, P3, T> CompositeProjectionOptionsStep<?, T> composite(TriFuncti
386387
*/
387388
<T> ProjectionFinalStep<T> constant(T value);
388389

390+
/**
391+
* Delegating projection that creates the actual projection at query create time and provides access to query parameters.
392+
* <p>
393+
* Which projection exactly to create is defined by a function passed to the arguments of this projection.
394+
*
395+
* @param projectionCreator The function creating an actual projection.
396+
* @return A final DSL step in a parameterized projection definition.
397+
*/
398+
@Incubating
399+
<T> ProjectionFinalStep<T> withParameters(
400+
Function<? super NamedValues, ? extends ProjectionFinalStep<T>> projectionCreator);
401+
389402
/**
390403
* Extend the current factory with the given extension,
391404
* resulting in an extended factory offering different types of projections.

engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/spi/AbstractSearchProjectionFactory.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@
77
package org.hibernate.search.engine.search.projection.dsl.spi;
88

99
import java.util.List;
10+
import java.util.function.Function;
1011

1112
import org.hibernate.search.engine.common.dsl.spi.DslExtensionState;
13+
import org.hibernate.search.engine.search.common.NamedValues;
1214
import org.hibernate.search.engine.search.common.ValueConvert;
1315
import org.hibernate.search.engine.search.projection.SearchProjection;
1416
import org.hibernate.search.engine.search.projection.dsl.CompositeProjectionInnerStep;
@@ -125,6 +127,12 @@ public <T> ProjectionFinalStep<T> constant(T value) {
125127
return new StaticProjectionFinalStep<>( dslContext.scope().projectionBuilders().constant( value ) );
126128
}
127129

130+
@Override
131+
public <T> ProjectionFinalStep<T> withParameters(
132+
Function<? super NamedValues, ? extends ProjectionFinalStep<T>> projectionCreator) {
133+
return new StaticProjectionFinalStep<>( dslContext.scope().projectionBuilders().withParameters( projectionCreator ) );
134+
}
135+
128136
@Override
129137
public <T> T extension(SearchProjectionFactoryExtension<T, R, E> extension) {
130138
return DslExtensionState.returnIfSupported(

engine/src/main/java/org/hibernate/search/engine/search/projection/spi/SearchProjectionBuilderFactory.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,13 @@
77
package org.hibernate.search.engine.search.projection.spi;
88

99
import java.util.Map;
10+
import java.util.function.Function;
1011
import java.util.function.Supplier;
1112

1213
import org.hibernate.search.engine.backend.common.DocumentReference;
14+
import org.hibernate.search.engine.search.common.NamedValues;
1315
import org.hibernate.search.engine.search.projection.SearchProjection;
16+
import org.hibernate.search.engine.search.projection.dsl.ProjectionFinalStep;
1417
import org.hibernate.search.util.common.SearchException;
1518

1619
/**
@@ -52,4 +55,7 @@ public interface SearchProjectionBuilderFactory {
5255
*/
5356
<T> SearchProjection<T> byTypeName(Map<String, ? extends SearchProjection<? extends T>> inners);
5457

58+
<T> SearchProjection<T> withParameters(
59+
Function<? super NamedValues, ? extends ProjectionFinalStep<T>> projectionCreator);
60+
5561
}

0 commit comments

Comments
 (0)