Package org.hibernate.search.test.query.dsl

Source Code of org.hibernate.search.test.query.dsl.DSLTest

/*
* 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.query.dsl;

import static org.fest.assertions.Assertions.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;

import org.junit.Assert;

import org.apache.lucene.document.DateTools;
import org.apache.lucene.analysis.core.LowerCaseFilterFactory;
import org.apache.lucene.analysis.ngram.NGramFilterFactory;
import org.apache.lucene.analysis.snowball.SnowballPorterFilterFactory;
import org.apache.lucene.analysis.standard.StandardFilterFactory;
import org.apache.lucene.analysis.standard.StandardTokenizerFactory;
import org.apache.lucene.analysis.core.StopFilterFactory;
import org.apache.lucene.search.NumericRangeQuery;
import org.apache.lucene.search.Query;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.search.cfg.Environment;
import org.hibernate.search.FullTextQuery;
import org.hibernate.search.FullTextSession;
import org.hibernate.search.Search;
import org.hibernate.search.exception.SearchException;
import org.hibernate.search.annotations.Factory;
import org.hibernate.search.bridge.builtin.impl.String2FieldBridgeAdaptor;
import org.hibernate.search.cfg.SearchMapping;
import org.hibernate.search.query.dsl.BooleanJunction;
import org.hibernate.search.query.dsl.QueryBuilder;
import org.hibernate.search.query.dsl.Unit;
import org.hibernate.search.query.dsl.impl.ConnectedTermMatchingContext;
import org.hibernate.search.spatial.Coordinates;
import org.hibernate.search.spatial.impl.Point;
import org.hibernate.search.test.SearchTestBase;
import org.hibernate.search.testsupport.TestForIssue;
import org.hibernate.search.util.logging.impl.Log;
import org.hibernate.search.util.logging.impl.LoggerFactory;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

/**
* @author Emmanuel Bernard
* @author Hardy Ferentschik
*/
//DO NOT AUTO INDENT THIS FILE.
//MY DSL IS BEAUTIFUL, DUMB INDENTATION IS SCREWING IT UP
public class DSLTest extends SearchTestBase {
  private static final Log log = LoggerFactory.make();

  private final Calendar calendar = Calendar.getInstance();

  private FullTextSession fullTextSession;
  private Date february;

  @Before
  public void setUp() throws Exception {
    super.setUp();
    Session session = openSession();
    fullTextSession = Search.getFullTextSession( session );
    indexTestData();
  }

  @After
  public void tearDown() throws Exception {
    super.tearDown();
  }

  @Test
  public void testUseOfFieldBridge() throws Exception {
    Transaction transaction = fullTextSession.beginTransaction();
    final QueryBuilder monthQb = fullTextSession.getSearchFactory()
        .buildQueryBuilder().forEntity( Month.class ).get();

    Query query = monthQb.keyword().onField( "monthValue" ).matching( 2 ).createQuery();
    assertEquals( 1, fullTextSession.createFullTextQuery( query, Month.class ).getResultSize() );

    query = monthQb.keyword()
        .onField( "monthValue" )
          .ignoreFieldBridge()
        .matching( "2" )
        .createQuery();
    assertEquals( 1, fullTextSession.createFullTextQuery( query, Month.class ).getResultSize() );
    transaction.commit();
  }

  @Test
  public void testUseOfCustomFieldBridgeInstance() throws Exception {
    Transaction transaction = fullTextSession.beginTransaction();
    final QueryBuilder monthQb = fullTextSession.getSearchFactory()
        .buildQueryBuilder().forEntity( Month.class ).get();

    ConnectedTermMatchingContext termMatchingContext = (ConnectedTermMatchingContext) monthQb
        .keyword()
        .onField( MonthClassBridge.FIELD_NAME_1 );

    Query query = termMatchingContext
        .withFieldBridge( new String2FieldBridgeAdaptor( new RomanNumberFieldBridge() ) )
        .matching( 2 )
        .createQuery();

    assertEquals( 1, fullTextSession.createFullTextQuery( query, Month.class ).getResultSize() );
    transaction.commit();
  }

  @Test
  public void testUseOfMultipleCustomFieldBridgeInstances() throws Exception {
    Transaction transaction = fullTextSession.beginTransaction();
    final QueryBuilder monthQb = fullTextSession.getSearchFactory()
        .buildQueryBuilder().forEntity( Month.class ).get();

    //Rather complex code here as we're not exposing the #withFieldBridge methods on the public interface
    final ConnectedTermMatchingContext field1Context = (ConnectedTermMatchingContext) monthQb
        .keyword()
        .onField( MonthClassBridge.FIELD_NAME_1 );

    final ConnectedTermMatchingContext field2Context = (ConnectedTermMatchingContext) field1Context
          .withFieldBridge( new String2FieldBridgeAdaptor( new RomanNumberFieldBridge() ) )
        .andField( MonthClassBridge.FIELD_NAME_2 );

    Query query = field2Context
          .withFieldBridge( new String2FieldBridgeAdaptor( new RomanNumberFieldBridge() ) )
          .matching( 2 )
        .createQuery();

    assertEquals( 1, fullTextSession.createFullTextQuery( query, Month.class ).getResultSize() );
    transaction.commit();
  }

  @Test
  public void testTermQueryOnAnalyzer() throws Exception {
    Transaction transaction = fullTextSession.beginTransaction();
    final QueryBuilder monthQb = fullTextSession.getSearchFactory()
        .buildQueryBuilder().forEntity( Month.class ).get();

    //regular term query
    Query query = monthQb.keyword().onField( "mythology" ).matching( "cold" ).createQuery();

    assertEquals( 0, fullTextSession.createFullTextQuery( query, Month.class ).getResultSize() );

    //term query based on several words
    query = monthQb.keyword().onField( "mythology" ).matching( "colder darker" ).createQuery();

    assertEquals( 1, fullTextSession.createFullTextQuery( query, Month.class ).getResultSize() );

    //term query applying the analyzer and generating one term per word
    query = monthQb.keyword().onField( "mythology_stem" ).matching( "snowboard" ).createQuery();

    assertEquals( 1, fullTextSession.createFullTextQuery( query, Month.class ).getResultSize() );

    //term query applying the analyzer and generating several terms per word
    query = monthQb.keyword().onField( "mythology_ngram" ).matching( "snobored" ).createQuery();

    assertEquals( 1, fullTextSession.createFullTextQuery( query, Month.class ).getResultSize() );

    //term query not using analyzers
    query = monthQb.keyword().onField( "mythology" ).ignoreAnalyzer().matching( "Month" ).createQuery();

    assertEquals( 0, fullTextSession.createFullTextQuery( query, Month.class ).getResultSize() );

    transaction.commit();
  }

  @Test
  public void testFuzzyAndWildcardQuery() throws Exception {
    Transaction transaction = fullTextSession.beginTransaction();
    final QueryBuilder monthQb = fullTextSession.getSearchFactory()
        .buildQueryBuilder().forEntity( Month.class ).get();


    //fuzzy search with custom threshold and prefix
    Query query = monthQb
        .keyword()
          .fuzzy()
            .withThreshold( .8f )
            .withPrefixLength( 1 )
          .onField( "mythology" )
          .matching( "calder" )
          .createQuery();

    assertEquals( 1, fullTextSession.createFullTextQuery( query, Month.class ).getResultSize() );

    //fuzzy search on multiple fields
    query = monthQb
        .keyword()
        .fuzzy()
        .withThreshold( .8f )
        .withPrefixLength( 1 )
        .onFields( "mythology", "history" )
        .matching( "showboarding" )
        .createQuery();

    assertEquals( 2, fullTextSession.createFullTextQuery( query, Month.class ).getResultSize() );

    //wildcard query
    query = monthQb
        .keyword()
          .wildcard()
          .onField( "mythology" )
          .matching( "mon*" )
          .createQuery();

    assertEquals( 3, fullTextSession.createFullTextQuery( query, Month.class ).getResultSize() );

    transaction.commit();
  }

  @Test
  @SuppressWarnings("unchecked")
  public void testQueryCustomization() throws Exception {
    Transaction transaction = fullTextSession.beginTransaction();
    final QueryBuilder monthQb = fullTextSession.getSearchFactory()
        .buildQueryBuilder().forEntity( Month.class ).get();


    //combined query, January and february both contain whitening but February in a longer text
    Query query = monthQb
        .bool()
        .should( monthQb.keyword().onField( "mythology" ).matching( "whitening" ).createQuery() )
        .should( monthQb.keyword().onField( "history" ).matching( "whitening" ).createQuery() )
        .createQuery();

    List<Month> results = fullTextSession.createFullTextQuery( query, Month.class ).list();
    assertEquals( 2, results.size() );
    assertEquals( "January", results.get( 0 ).getName() );

    //boosted query, January and february both contain whitening but February in a longer text
    //since history is boosted, February should come first though
    query = monthQb
        .bool()
        .should( monthQb.keyword().onField( "mythology" ).matching( "whitening" ).createQuery() )
        .should( monthQb.keyword().onField( "history" ).boostedTo( 30 ).matching( "whitening" ).createQuery() )
        .createQuery();

    results = fullTextSession.createFullTextQuery( query, Month.class ).list();
    assertEquals( 2, results.size() );
    assertEquals( "February", results.get( 0 ).getName() );

    //FIXME add other method tests besides boostedTo

    transaction.commit();
  }

  @Test
  @SuppressWarnings("unchecked")
  public void testMultipleFields() throws Exception {
    Transaction transaction = fullTextSession.beginTransaction();
    final QueryBuilder monthQb = fullTextSession.getSearchFactory()
        .buildQueryBuilder().forEntity( Month.class ).get();

    //combined query, January and february both contain whitening but February in a longer text
    Query query = monthQb.keyword()
        .onField( "mythology" )
        .andField( "history" )
        .matching( "whitening" )
        .createQuery();

    List<Month> results = fullTextSession.createFullTextQuery( query, Month.class ).list();
    assertEquals( 2, results.size() );
    assertEquals( "January", results.get( 0 ).getName() );

    //combined query, January and february both contain whitening but February in a longer text
    query = monthQb.keyword()
        .onFields( "mythology", "history" )
          .boostedTo( 30 )
        .matching( "whitening" ).createQuery();

    results = fullTextSession.createFullTextQuery( query, Month.class ).list();
    assertEquals( 2, results.size() );
    assertEquals( "January", results.get( 0 ).getName() );

    //boosted query, January and february both contain whitening but February in a longer text
    //since history is boosted, February should come first though
    query = monthQb.keyword()
        .onField( "mythology" )
        .andField( "history" )
          .boostedTo( 30 )
        .matching( "whitening" )
        .createQuery();

    results = fullTextSession.createFullTextQuery( query, Month.class ).list();
    assertEquals( 2, results.size() );
    assertEquals( "February", results.get( 0 ).getName() );

    transaction.commit();
  }

  @Test
  @SuppressWarnings("unchecked")
  public void testBoolean() throws Exception {
    Transaction transaction = fullTextSession.beginTransaction();
    final QueryBuilder monthQb = fullTextSession.getSearchFactory()
        .buildQueryBuilder().forEntity( Month.class ).get();

    //must
    Query query = monthQb
        .bool()
        .must( monthQb.keyword().onField( "mythology" ).matching( "colder" ).createQuery() )
        .createQuery();

    List<Month> results = fullTextSession.createFullTextQuery( query, Month.class ).list();
    assertEquals( 1, results.size() );
    assertEquals( "January", results.get( 0 ).getName() );

    //must not + all
    query = monthQb
        .bool()
          .should( monthQb.all().createQuery() )
          .must( monthQb.keyword().onField( "mythology" ).matching( "colder" ).createQuery() )
            .not()
          .createQuery();

    results = fullTextSession.createFullTextQuery( query, Month.class ).list();
    assertEquals( 2, results.size() );
    assertEquals( "February", results.get( 0 ).getName() );
    assertEquals( "March", results.get( 1 ).getName() );

    //implicit must not + all (not recommended)
    query = monthQb
        .bool()
          .must( monthQb.keyword().onField( "mythology" ).matching( "colder" ).createQuery() )
            .not()
          .createQuery();
    results = fullTextSession.createFullTextQuery( query, Month.class ).list();
    assertEquals( 2, results.size() );
    assertEquals( "February", results.get( 0 ).getName() );
    assertEquals( "March", results.get( 1 ).getName() );

    //all except (recommended)
    query = monthQb
        .all()
          .except( monthQb.keyword().onField( "mythology" ).matching( "colder" ).createQuery() )
        .createQuery();

    results = fullTextSession.createFullTextQuery( query, Month.class ).list();
    assertEquals( 2, results.size() );
    assertEquals( "February", results.get( 0 ).getName() );
    assertEquals( "March", results.get( 1 ).getName() );


    transaction.commit();
  }

  @Test(expected = SearchException.class)
  public void testIllegalBooleanJunction() {
    final QueryBuilder monthQb = fullTextSession.getSearchFactory()
        .buildQueryBuilder().forEntity( Month.class ).get();
    //forgetting to set any condition on the boolean, an exception shall be thrown:
    BooleanJunction<BooleanJunction> booleanJunction = monthQb.bool();
    assertTrue( booleanJunction.isEmpty() );
    Query query = booleanJunction.createQuery();
    Assert.fail( "should not reach this point" );
  }

  @Test
  public void testRangeQueryFromTo() throws Exception {
    Transaction transaction = fullTextSession.beginTransaction();
    final QueryBuilder monthQb = fullTextSession.getSearchFactory()
        .buildQueryBuilder().forEntity( Month.class ).get();

    calendar.setTimeZone( TimeZone.getTimeZone( "UTC" ) );
    calendar.set( 1900, 2, 12, 0, 0, 0 );
    Date from = calendar.getTime();
    calendar.set( 1910, 2, 12, 0, 0, 0 );
    Date to = calendar.getTime();

    Query query = monthQb
        .range()
          .onField( "estimatedCreation" )
          .andField( "justfortest" )
            .ignoreFieldBridge().ignoreAnalyzer()
          .from( from )
          .to( to ).excludeLimit()
          .createQuery();

    assertEquals( 1, fullTextSession.createFullTextQuery( query, Month.class ).getResultSize() );

    query = monthQb
        .range()
          .onField( "estimatedCreation" )
            .ignoreFieldBridge()
          .andField( "justfortest" )
            .ignoreFieldBridge().ignoreAnalyzer()
          .from( DateTools.dateToString( from, DateTools.Resolution.MINUTE ) )
          .to( DateTools.dateToString( to, DateTools.Resolution.MINUTE ) )
            .excludeLimit()
          .createQuery();
    assertEquals( 1, fullTextSession.createFullTextQuery( query, Month.class ).getResultSize() );
    transaction.commit();
  }

  @Test
  public void testRangeQueryBelow() throws Exception {
    Transaction transaction = fullTextSession.beginTransaction();
    final QueryBuilder monthQb = fullTextSession.getSearchFactory()
        .buildQueryBuilder().forEntity( Month.class ).get();

    calendar.setTimeZone( TimeZone.getTimeZone( "UTC" ) );
    calendar.set( 10 + 1800, 2, 12, 0, 0, 0 );
    Date to = calendar.getTime();

    Query query = monthQb
        .range()
          .onField( "estimatedCreation" )
          .andField( "justfortest" )
            .ignoreFieldBridge().ignoreAnalyzer()
          .below( to )
          .createQuery();

    FullTextQuery hibQuery = fullTextSession.createFullTextQuery( query, Month.class );
    assertEquals( 1, hibQuery.getResultSize() );
    assertEquals( "March", ( (Month) hibQuery.list().get( 0 ) ).getName() );

    query = monthQb
        .range()
          .onField( "estimatedCreation" )
            .ignoreFieldBridge()
          .andField( "justfortest" )
            .ignoreFieldBridge().ignoreAnalyzer()
          .below( DateTools.dateToString( to, DateTools.Resolution.MINUTE ) )
          .createQuery();

    hibQuery = fullTextSession.createFullTextQuery( query, Month.class );
    assertEquals( 1, hibQuery.getResultSize() );
    assertEquals( "March", ( (Month) hibQuery.list().get( 0 ) ).getName() );

    query = monthQb.range()
        .onField( "raindropInMm" )
        .below( 0.24d )
        .createQuery();

    assertTrue( query.getClass().isAssignableFrom( NumericRangeQuery.class ) );

    List<?> results = fullTextSession.createFullTextQuery( query, Month.class ).list();

    assertEquals( "test range numeric ", 1, results.size() );
    assertEquals( "test range numeric ", "January", ( (Month) results.get( 0 ) ).getName() );

    transaction.commit();
  }

  @Test
  public void testRangeQueryAbove() throws Exception {
    Transaction transaction = fullTextSession.beginTransaction();
    final QueryBuilder monthQb = fullTextSession.getSearchFactory()
        .buildQueryBuilder().forEntity( Month.class ).get();

    calendar.setTimeZone( TimeZone.getTimeZone( "UTC" ) );
    calendar.set( 10 + 1900, 2, 12, 0, 0, 0 );
    Date to = calendar.getTime();

    Query query = monthQb
        .range()
          .onField( "estimatedCreation" )
          .andField( "justfortest" )
            .ignoreFieldBridge().ignoreAnalyzer()
          .above( to )
          .createQuery();
    FullTextQuery hibQuery = fullTextSession.createFullTextQuery( query, Month.class );
    assertEquals( 1, hibQuery.getResultSize() );
    assertEquals( "February", ( (Month) hibQuery.list().get( 0 ) ).getName() );

    query = monthQb
        .range()
          .onField( "estimatedCreation" )
            .ignoreFieldBridge()
          .andField( "justfortest" )
            .ignoreFieldBridge().ignoreAnalyzer()
          .above( DateTools.dateToString( to, DateTools.Resolution.MINUTE ) )
          .createQuery();
    hibQuery = fullTextSession.createFullTextQuery( query, Month.class );
    assertEquals( 1, hibQuery.getResultSize() );
    assertEquals( "February", ( (Month) hibQuery.list().get( 0 ) ).getName() );

    // test the limits, inclusive
    query = monthQb
        .range()
          .onField( "estimatedCreation" )
          .andField( "justfortest" )
            .ignoreFieldBridge().ignoreAnalyzer()
          .above( february )
          .createQuery();
    hibQuery = fullTextSession.createFullTextQuery( query, Month.class );
    assertEquals( 1, hibQuery.getResultSize() );
    assertEquals( "February", ( (Month) hibQuery.list().get( 0 ) ).getName() );

    // test the limits, exclusive
    query = monthQb
        .range()
          .onField( "estimatedCreation" )
          .andField( "justfortest" )
            .ignoreFieldBridge().ignoreAnalyzer()
          .above( february ).excludeLimit()
          .createQuery();
    hibQuery = fullTextSession.createFullTextQuery( query, Month.class );
    assertEquals( 0, hibQuery.getResultSize() );

    transaction.commit();
  }

  @Test
  public void testPhraseQuery() throws Exception {
    Transaction transaction = fullTextSession.beginTransaction();
    final QueryBuilder monthQb = fullTextSession.getSearchFactory()
        .buildQueryBuilder().forEntity( Month.class ).get();

    Query query = monthQb
        .phrase()
          .onField( "mythology" )
          .sentence( "colder and whitening" )
          .createQuery();

    assertEquals(
        "test exact phrase", 1, fullTextSession.createFullTextQuery( query, Month.class ).getResultSize()
    );

    query = monthQb
        .phrase()
          .onField( "mythology" )
          .sentence( "Month whitening" )
          .createQuery();

    assertEquals( "test slop", 0, fullTextSession.createFullTextQuery( query, Month.class ).getResultSize() );

    query = monthQb
        .phrase()
          .withSlop( 3 )
          .onField( "mythology" )
          .sentence( "Month whitening" )
          .createQuery();

    assertEquals( "test slop", 1, fullTextSession.createFullTextQuery( query, Month.class ).getResultSize() );

    query = monthQb
        .phrase()
          .onField( "mythology" )
          .sentence( "whitening" )
          .createQuery();

    assertEquals(
        "test one term optimization",
        1,
        fullTextSession.createFullTextQuery( query, Month.class ).getResultSize()
    );


    //Does not work as the NGram filter does not seem to be skipping posiional increment between ngrams.
//    query = monthQb
//        .phrase()
//          .onField( "mythology_ngram" )
//          .sentence( "snobored" )
//          .createQuery();
//
//    assertEquals( 1, fullTextSession.createFullTextQuery( query, Month.class ).getResultSize() );

    transaction.commit();
  }

  @Test
  @TestForIssue(jiraKey = "HSEARCH-1074")
  public void testPhraseQueryWithNoTermsAfterAnalyzerApplication() throws Exception {
    Transaction transaction = fullTextSession.beginTransaction();
    final QueryBuilder monthQb = fullTextSession.getSearchFactory()
        .buildQueryBuilder().forEntity( Month.class ).get();

    Query query = monthQb.
        phrase()
        .onField( "mythology" )
        .sentence( "and" )
        .createQuery();

    assertEquals(
        "there should be no results, since all terms are stop words",
        0,
        fullTextSession.createFullTextQuery( query, Month.class ).getResultSize()
    );
    transaction.commit();
  }

  @Test
  public void testNumericRangeQueries() {
    Transaction transaction = fullTextSession.beginTransaction();
    final QueryBuilder monthQb = fullTextSession.getSearchFactory()
        .buildQueryBuilder().forEntity( Month.class ).get();

    Query query = monthQb
        .range()
          .onField( "raindropInMm" )
          .from( 0.23d )
          .to( 0.24d )
          .createQuery();

    assertTrue( query.getClass().isAssignableFrom( NumericRangeQuery.class ) );

    List<?> results = fullTextSession.createFullTextQuery( query, Month.class ).list();

    assertEquals( "test range numeric ", 1, results.size() );
    assertEquals( "test range numeric ", "January", ( (Month) results.get( 0 ) ).getName() );


    transaction.commit();
  }

  @Test
  @TestForIssue( jiraKey = "HSEARCH-1378")
  public void testNumericRangeQueryAbove() {
    Transaction transaction = fullTextSession.beginTransaction();
    final QueryBuilder monthQb = fullTextSession.getSearchFactory()
        .buildQueryBuilder().forEntity( Month.class ).get();

    //inclusive
    Query query = monthQb
        .range()
          .onField( "raindropInMm" )
          .above( 0.231d )
          .createQuery();

    assertTrue( query.getClass().isAssignableFrom( NumericRangeQuery.class ) );

    List<?> results = fullTextSession.createFullTextQuery( query, Month.class ).list();
    assertThat( results ).onProperty( "name" ).containsOnly( "January", "February", "March" );

    //exclusive
    query = monthQb
        .range()
          .onField( "raindropInMm" )
          .above( 0.231d )
          .excludeLimit()
          .createQuery();

    results = fullTextSession.createFullTextQuery( query, Month.class ).list();
    assertThat( results ).onProperty( "name" ).containsOnly( "February", "March" );

    transaction.commit();
  }

  @Test
  @TestForIssue( jiraKey = "HSEARCH-1378")
  public void testNumericRangeQueryBelow() {
    Transaction transaction = fullTextSession.beginTransaction();
    final QueryBuilder monthQb = fullTextSession.getSearchFactory()
        .buildQueryBuilder().forEntity( Month.class ).get();

    //inclusive
    Query query = monthQb
        .range()
          .onField( "raindropInMm" )
          .below( 0.435d )
          .createQuery();

    assertTrue( query.getClass().isAssignableFrom( NumericRangeQuery.class ) );

    List<?> results = fullTextSession.createFullTextQuery( query, Month.class ).list();
    assertThat( results ).onProperty( "name" ).containsOnly( "January", "February", "March" );

    //exclusive
    query = monthQb
        .range()
          .onField( "raindropInMm" )
          .below( 0.435d )
          .excludeLimit()
          .createQuery();

    results = fullTextSession.createFullTextQuery( query, Month.class ).list();
    assertThat( results ).onProperty( "name" ).containsOnly( "January" );

    transaction.commit();
  }

  @Test
  public void testNumericFieldsTermQuery() {
    Transaction transaction = fullTextSession.beginTransaction();
    final QueryBuilder monthQb = fullTextSession.getSearchFactory()
        .buildQueryBuilder().forEntity( Month.class ).get();

    Query query = monthQb.keyword()
        .onField( "raindropInMm" )
        .matching( 0.231d )
        .createQuery();

    assertTrue( query.getClass().isAssignableFrom( NumericRangeQuery.class ) );

    assertEquals(
        "test term numeric ", 1, fullTextSession.createFullTextQuery( query, Month.class ).getResultSize()
    );

    transaction.commit();
  }

  @Test
  public void testFieldBridge() {
    Transaction transaction = fullTextSession.beginTransaction();
    final QueryBuilder monthQb = fullTextSession.getSearchFactory()
        .buildQueryBuilder().forEntity( Month.class ).get();
    Query query = monthQb.keyword()
        .onField( "monthRomanNumber" )
        .matching( 2 )
        .createQuery();
    FullTextQuery fullTextQuery = fullTextSession.createFullTextQuery( query, Month.class );
    List<?> results = fullTextQuery.list();
    assertEquals( 1, results.size() );
    Month february = (Month) results.get( 0 );
    assertEquals( 2, february.getMonthValue() );
    transaction.commit();
  }

  @Test
  public void testSpatialQueries() {
    Transaction transaction = fullTextSession.beginTransaction();
    final QueryBuilder builder = fullTextSession.getSearchFactory()
        .buildQueryBuilder().forEntity( POI.class ).get();

    Coordinates coordinates = Point.fromDegrees( 24d, 31.5d );
    Query query = builder
        .spatial()
          .onCoordinates( "location" )
          .within( 51, Unit.KM )
            .ofCoordinates( coordinates )
          .createQuery();

    List<?> results = fullTextSession.createFullTextQuery( query, POI.class ).list();

    assertEquals( "test spatial hash based spatial query", 1, results.size() );
    assertEquals( "test spatial hash based spatial query", "Bozo", ( (POI) results.get( 0 ) ).getName() );

    query = builder
        .spatial()
          .onCoordinates( "location" )
          .within( 500, Unit.KM )
            .ofLatitude( 48.858333d ).andLongitude( 2.294444d )
          .createQuery();
    results = fullTextSession.createFullTextQuery( query, POI.class ).list();

    assertEquals( "test spatial hash based spatial query", 1, results.size() );
    assertEquals( "test spatial hash based spatial query", "Tour Eiffel", ( (POI) results.get( 0 ) ).getName() );

    transaction.commit();
  }

  @Test
  @TestForIssue( jiraKey = "HSEARCH-703" )
  public void testPolymorphicQueryForUnindexedSuperTypeReturnsIndexedSubType() {
    Transaction transaction = fullTextSession.beginTransaction();

    final QueryBuilder builder = fullTextSession
        .getSearchFactory()
        .buildQueryBuilder()
        .forEntity( Object.class )
        .get();

    Query query = builder.all().createQuery();
    List<?> results = fullTextSession.createFullTextQuery( query, Object.class ).list();

    assertEquals( "expected all instances of all indexed types", 7, results.size() );

    transaction.commit();
  }

  @Test
  @TestForIssue( jiraKey = "HSEARCH-703" )
  public void testPolymorphicQueryWithKeywordTermForUnindexedSuperTypeReturnsIndexedSubType() {
    Transaction transaction = fullTextSession.beginTransaction();

    final QueryBuilder builder = fullTextSession
        .getSearchFactory()
        .buildQueryBuilder()
        .forEntity( Car.class )
        .get();

    Query query = builder.keyword().onField( "name" ).matching( "Morris" ).createQuery();
    List<?> results = fullTextSession.createFullTextQuery( query ).list();

    assertEquals( "expected one instance of indexed sub-type", 1, results.size() );
    assertEquals( 180, ( (SportsCar) results.get( 0 ) ).getEnginePower() );

    transaction.commit();
  }

  @Test
  @TestForIssue( jiraKey = "HSEARCH-703" )
  public void testObtainingBuilderForUnindexedTypeWithoutIndexedSubTypesCausesException() {
    Transaction transaction = fullTextSession.beginTransaction();

    try {
      fullTextSession
        .getSearchFactory()
        .buildQueryBuilder()
        .forEntity( Animal.class )
        .get();

      fail( "Obtaining a builder not allowed for unindexed type without any indexed sub-types." );
    }
    catch (SearchException e) {
      // success
    }
    finally {
      transaction.commit();
    }
  }

  private void outputQueryAndResults(boolean outputLogs, Coffee originalInstance, Query mltQuery, List<Object[]> results) {
    // set to true to display results
    if ( outputLogs ) {
      StringBuilder builder = new StringBuilder( "Initial coffee: " )
          .append( originalInstance ) .append( "\n\n" )
          .append( "Query: " ).append( mltQuery.toString() ).append( "\n\n" )
          .append( "Matching coffees" ).append( "\n" );
      for ( Object[] entry : results ) {
        builder.append( "    Score: " ).append( entry[1] );
        builder.append( " | Coffee: " ).append( entry[0] ).append( "\n" );
      }
      log.debug( builder.toString() );
    }
  }

  private void indexTestData() {
    Transaction tx = fullTextSession.beginTransaction();
    final Calendar calendar = Calendar.getInstance();
    calendar.setTimeZone( TimeZone.getTimeZone( "UTC" ) );
    calendar.set( 1900, 2, 12, 0, 0, 0 );
    Date january = calendar.getTime();
    fullTextSession.persist(
        new Month(
            "January",
            1,
            "Month of colder and whitening",
            "Historically colder than any other month in the northern hemisphere",
            january,
            0.231d
        )
    );
    calendar.set( 100 + 1900, 2, 12, 0, 0, 0 );
    february = calendar.getTime();
    fullTextSession.persist(
        new Month(
            "February",
            2,
            "Month of snowboarding",
            "Historically, the month where we make babies while watching the whitening landscape",
            february,
            0.435d
        )
    );
    calendar.set( 1800, 2, 12, 0, 0, 0 );
    Date march = calendar.getTime();
    fullTextSession.persist(
        new Month(
            "March",
            3,
            "Month of fake spring",
            "Historically, the month in which we actually find time to go snowboarding.",
            march,
            0.435d
        )
    );

    POI poi = new POI( 1, "Tour Eiffel", 48.858333d, 2.294444d, "Monument" );
    fullTextSession.persist( poi );
    poi = new POI( 2, "Bozo", 24d, 32d, "Monument" );
    fullTextSession.persist( poi );

    Car car = new SportsCar( 1, "Leyland", 100 );
    fullTextSession.persist( car );

    car = new SportsCar( 2, "Morris", 180 );
    fullTextSession.persist( car );

    tx.commit();
    fullTextSession.clear();
  }

  @Override
  protected Class<?>[] getAnnotatedClasses() {
    return new Class<?>[] {
        Month.class,
        POI.class,
        Car.class,
        SportsCar.class,
        Animal.class
    };
  }

  @Override
  protected void configure(Configuration cfg) {
    super.configure( cfg );
    cfg.getProperties().put( Environment.MODEL_MAPPING, MappingFactory.class.getName() );
  }

  public static class MappingFactory {
    @Factory
    public SearchMapping build() {
      SearchMapping mapping = new SearchMapping();
      mapping
          .analyzerDef( "stemmer", StandardTokenizerFactory.class )
          .filter( StandardFilterFactory.class )
          .filter( LowerCaseFilterFactory.class )
          .filter( StopFilterFactory.class )
          .filter( SnowballPorterFilterFactory.class )
          .param( "language", "English" )
          .analyzerDef( "ngram", StandardTokenizerFactory.class )
          .filter( StandardFilterFactory.class )
          .filter( LowerCaseFilterFactory.class )
          .filter( StopFilterFactory.class )
          .filter( NGramFilterFactory.class )
          .param( "minGramSize", "3" )
          .param( "maxGramSize", "3" );
      return mapping;
    }
  }
}
TOP

Related Classes of org.hibernate.search.test.query.dsl.DSLTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.