Skip to content

Commit

Permalink
HSEARCH-3591 Add an API to mix imperative and declarative style when …
Browse files Browse the repository at this point in the history
…building composite sorts

See in particular IndexSearchDocumentRepositoryImpl#searchAroundMe to
get an idea of why we need this.
  • Loading branch information
yrodiere committed Jun 6, 2019
1 parent cac7337 commit 7f8a182
Show file tree
Hide file tree
Showing 8 changed files with 358 additions and 64 deletions.
@@ -0,0 +1,35 @@
/*
* Hibernate Search, full-text search for your domain model
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.search.engine.search.dsl.sort;

import org.hibernate.search.engine.search.SearchSort;

/**
* The context used when defining a composite sort explicitly
* (not using {@link NonEmptySortContext#then()}).
*/
public interface CompositeSortContext extends NonEmptySortContext {

/**
* Add an element to the composite sort based on a previously-built {@link SearchSort}.
*
* @param searchSort The predicate that must match.
* @return {@code this}, for method chaining.
*/
CompositeSortContext add(SearchSort searchSort);

/**
* Add an element to the composite sort based on an almost-built {@link SearchSort}.
*
* @param terminalContext The terminal context allowing to retrieve a {@link SearchSort}.
* @return {@code this}, for method chaining.
*/
default CompositeSortContext add(SearchSortTerminalContext terminalContext) {
return add( terminalContext.toSort() );
}

}
Expand Up @@ -6,6 +6,8 @@
*/
package org.hibernate.search.engine.search.dsl.sort;

import java.util.function.Consumer;

import org.hibernate.search.engine.search.SearchSort;
import org.hibernate.search.engine.spatial.GeoPoint;
import org.hibernate.search.util.common.SearchException;
Expand Down Expand Up @@ -86,6 +88,43 @@ default DistanceSortContext byDistance(String absoluteFieldPath, double latitude
*/
NonEmptySortContext by(SearchSort sort);

/**
* Order by a sort composed of several elements.
* <p>
* Note that, in general, calling this method is not necessary as you can chain sorts by calling
* {@link NonEmptySortContext#then()}.
* This method is mainly useful to mix imperative and declarative style when building sorts.
* See {@link #byComposite(Consumer)}
*
* @return A context allowing to define the sort more precisely, {@link NonEmptySortContext#then() chain other sorts}
* or {@link SearchSortTerminalContext#toSort() get the resulting sort}.
*/
CompositeSortContext byComposite();

/**
* Order by a sort composed of several elements,
* which will be defined by the given consumer.
* <p>
* Best used with lambda expressions.
* <p>
* This is mainly useful to mix imperative and declarative style when building sorts, e.g.:
* <pre>{@code
* f.composite( c -> {
* c.add( f.byField( "category" ) );
* if ( someInput != null ) {
* c.add( f.byDistance( "location", someInput.getLatitude(), someInput.getLongitude() );
* }
* c.add( f.byIndexOrder() );
* } )
* }</pre>
*
* @param elementContributor A consumer that will add elements to the context passed in parameter.
* Should generally be a lambda expression.
* @return A context allowing {@link NonEmptySortContext#then() chain other sorts}
* or {@link SearchSortTerminalContext#toSort() get the resulting sort}.
*/
NonEmptySortContext byComposite(Consumer<? super CompositeSortContext> elementContributor);

/**
* Extend the current context with the given extension,
* resulting in an extended context offering different types of sorts.
Expand Down
@@ -0,0 +1,38 @@
/*
* Hibernate Search, full-text search for your domain model
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.search.engine.search.dsl.sort.impl;

import org.hibernate.search.engine.search.SearchSort;
import org.hibernate.search.engine.search.dsl.sort.CompositeSortContext;
import org.hibernate.search.engine.search.dsl.sort.SearchSortFactoryContext;
import org.hibernate.search.engine.search.dsl.sort.spi.SearchSortDslContext;

class CompositeSortContextImpl<B> implements CompositeSortContext {

private SearchSortDslContext<?, B> dslContext;

CompositeSortContextImpl(SearchSortDslContext<?, B> dslContext) {
this.dslContext = dslContext;
}

@Override
public CompositeSortContext add(SearchSort searchSort) {
dslContext = dslContext.append( dslContext.getFactory().toImplementation( searchSort ) );
return this;
}

@Override
public SearchSortFactoryContext then() {
return new DefaultSearchSortFactoryContext<>( dslContext );
}

@Override
public SearchSort toSort() {
return dslContext.toSort();
}

}
Expand Up @@ -6,8 +6,11 @@
*/
package org.hibernate.search.engine.search.dsl.sort.impl;

import java.util.function.Consumer;

import org.hibernate.search.engine.common.dsl.spi.DslExtensionState;
import org.hibernate.search.engine.search.SearchSort;
import org.hibernate.search.engine.search.dsl.sort.CompositeSortContext;
import org.hibernate.search.engine.search.dsl.sort.DistanceSortContext;
import org.hibernate.search.engine.search.dsl.sort.FieldSortContext;
import org.hibernate.search.engine.search.dsl.sort.NonEmptySortContext;
Expand Down Expand Up @@ -55,6 +58,18 @@ public DistanceSortContext byDistance(String absoluteFieldPath, GeoPoint locatio
);
}

@Override
public CompositeSortContext byComposite() {
return new CompositeSortContextImpl<>( dslContext );
}

@Override
public NonEmptySortContext byComposite(Consumer<? super CompositeSortContext> elementContributor) {
CompositeSortContext context = byComposite();
elementContributor.accept( context );
return context;
}

@Override
public <T> T extension(SearchSortFactoryContextExtension<T> extension) {
return DslExtensionState.returnIfSupported(
Expand Down
Expand Up @@ -6,7 +6,10 @@
*/
package org.hibernate.search.engine.search.dsl.sort.spi;

import java.util.function.Consumer;

import org.hibernate.search.engine.search.SearchSort;
import org.hibernate.search.engine.search.dsl.sort.CompositeSortContext;
import org.hibernate.search.engine.search.dsl.sort.DistanceSortContext;
import org.hibernate.search.engine.search.dsl.sort.FieldSortContext;
import org.hibernate.search.engine.search.dsl.sort.NonEmptySortContext;
Expand Down Expand Up @@ -59,6 +62,16 @@ public NonEmptySortContext by(SearchSort sort) {
return delegate.by( sort );
}

@Override
public CompositeSortContext byComposite() {
return delegate.byComposite();
}

@Override
public NonEmptySortContext byComposite(Consumer<? super CompositeSortContext> elementContributor) {
return delegate.byComposite( elementContributor );
}

@Override
public <T> T extension(SearchSortFactoryContextExtension<T> extension) {
return delegate.extension( extension );
Expand Down

0 comments on commit 7f8a182

Please sign in to comment.