/* * 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.test.sorting; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.apache.lucene.index.IndexReader; import org.apache.lucene.search.Sort; import org.apache.lucene.search.SortField; import org.apache.lucene.search.SortField.Type; import org.hibernate.search.annotations.DocumentId; import org.hibernate.search.annotations.Indexed; import org.hibernate.search.engine.integration.impl.ExtendedSearchIntegrator; import org.hibernate.search.engine.metadata.impl.SortableFieldMetadata; import org.hibernate.search.engine.spi.EntityIndexBinding; import org.hibernate.search.filter.impl.FullTextFilterImpl; import org.hibernate.search.indexes.spi.IndexManager; import org.hibernate.search.query.engine.impl.SortConfigurations; import org.hibernate.search.reader.impl.ManagedMultiReader; import org.hibernate.search.reader.impl.MultiReaderFactory; import org.hibernate.search.testsupport.junit.SearchFactoryHolder; import org.hibernate.search.testsupport.junit.SkipOnElasticsearch; import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; import static org.fest.assertions.Assertions.assertThat; /** * Test to verify that the uninverting reader is only applied if actually needed. * * @author Gunnar Morling */ @Category(SkipOnElasticsearch.class) // This test is specific to Lucene public class ManagedMultiReaderTest { @Rule public SearchFactoryHolder factoryHolder = new SearchFactoryHolder( Person.class, Customer.class ); @Test public void testStandardReaderIsUsedIfAllSortsAreCovered() throws Exception { ExtendedSearchIntegrator integrator = factoryHolder.getSearchFactory(); EntityIndexBinding binding = integrator.getIndexBinding( Person.class ); IndexManager[] indexManagers = binding.getSelectionStrategy().getIndexManagersForQuery( new FullTextFilterImpl[0] ); Sort sort = new Sort( new SortField( "ageForIntSorting", Type.INT ), new SortField( "ageForStringSorting", Type.STRING ) ); SortConfigurations configuredSorts = new SortConfigurations.Builder() .setIndex( "test" ) .setEntityType( Person.class ) .addSortableFields( Arrays.asList( new SortableFieldMetadata.Builder( "ageForIntSorting" ).build(), new SortableFieldMetadata.Builder( "ageForStringSorting" ).build() ) ) .build(); try ( ManagedMultiReader reader = (ManagedMultiReader) MultiReaderFactory.openReader( configuredSorts, sort, indexManagers, false ) ) { List<? extends IndexReader> actualReaders = reader.getSubReaders(); assertThat( actualReaders ).hasSize( 1 ); assertThat( actualReaders.get( 0 ).getClass().getSimpleName() ).isEqualTo( "StandardDirectoryReader" ); } } @Test public void testUninvertingReaderIsUsedIfNotAllSortsAreCovered() throws Exception { ExtendedSearchIntegrator integrator = factoryHolder.getSearchFactory(); EntityIndexBinding binding = integrator.getIndexBinding( Person.class ); IndexManager[] indexManagers = binding.getSelectionStrategy().getIndexManagersForQuery( new FullTextFilterImpl[0] ); Sort sort = new Sort( new SortField( "ageForIntSorting", Type.INT ), new SortField( "ageForStringSorting", Type.STRING ) ); SortConfigurations configuredSorts = new SortConfigurations.Builder() .setIndex( "person" ) .setEntityType( Person.class ) .addSortableFields( Arrays.asList( new SortableFieldMetadata.Builder( "ageForStringSorting" ).build() ) ) .build(); try ( ManagedMultiReader reader = (ManagedMultiReader) MultiReaderFactory.openReader( configuredSorts, sort, indexManagers, true ) ) { List<? extends IndexReader> actualReaders = reader.getSubReaders(); assertThat( actualReaders ).hasSize( 1 ); assertThat( actualReaders.get( 0 ).getClass().getSimpleName() ).isEqualTo( "UninvertingDirectoryReader" ); } } @Test public void testCombinationOfStandardAndUninvertingReaderAsRequiredToSortOnInvolvedIndexes() throws Exception { ExtendedSearchIntegrator integrator = factoryHolder.getSearchFactory(); EntityIndexBinding binding = integrator.getIndexBinding( Person.class ); List<IndexManager> indexManagers = new ArrayList<>( Arrays.asList( binding.getSelectionStrategy().getIndexManagersForQuery( new FullTextFilterImpl[0] ) ) ); binding = integrator.getIndexBinding( Customer.class ); indexManagers.addAll( Arrays.asList( binding.getSelectionStrategy().getIndexManagersForQuery( new FullTextFilterImpl[0] ) ) ); Sort sort = new Sort( new SortField( "ageForIntSorting", Type.INT ), new SortField( "ageForStringSorting", Type.STRING ) ); SortConfigurations configuredSorts = new SortConfigurations.Builder() .setIndex( "person" ) .setEntityType( Person.class ) .addSortableFields( Arrays.asList( new SortableFieldMetadata.Builder( "ageForStringSorting" ).build() ) ) .setIndex( "customer" ) .setEntityType( Customer.class ) .addSortableFields( Arrays.asList( new SortableFieldMetadata.Builder( "ageForStringSorting" ).build(), new SortableFieldMetadata.Builder( "ageForIntSorting" ).build() ) ) .build(); try ( ManagedMultiReader reader = (ManagedMultiReader) MultiReaderFactory.openReader( configuredSorts, sort, indexManagers.toArray( new IndexManager[indexManagers.size()] ), true ) ) { List<? extends IndexReader> actualReaders = reader.getSubReaders(); assertThat( actualReaders ).hasSize( 2 ); assertThat( actualReaders.get( 0 ).getClass().getSimpleName() ).isEqualTo( "UninvertingDirectoryReader" ); assertThat( actualReaders.get( 1 ).getClass().getSimpleName() ).isEqualTo( "StandardDirectoryReader" ); } } @Indexed(index = "person") private class Person { @DocumentId int id; } @Indexed(index = "customer") private class Customer { @DocumentId int id; } }