.from( A.class ) .hasResultSize( 1 ); assertEquals( 1 , searchIntegrator.getStatistics().getSearchQueryExecutionCount() ); assertEquals( 1 , searchIntegrator.getStatistics().getIndexedClassNames().size() ); .from( A.class, B.class, C.class ) .hasResultSize( 1 ); assertEquals( 2 , searchIntegrator.getStatistics().getSearchQueryExecutionCount() ); assertEquals( 3 , searchIntegrator.getStatistics().getIndexedClassNames().size() ); .from( A.class, B.class, C.class ) .hasResultSize( 1 ); assertEquals( 3 , searchIntegrator.getStatistics().getSearchQueryExecutionCount() ); assertEquals( 3 , searchIntegrator.getStatistics().getIndexedClassNames().size() );
@Test @Category(SkipOnElasticsearch.class) // This only works because of a Lucene-specific hack in org.hibernate.search.bridge.util.impl.NumericFieldUtils.createNumericRangeQuery public void testRangeQueryAboveIgnoreFieldBridge() throws Exception { final QueryBuilder monthQb = helper.queryBuilder( Month.class ); calendar.setTimeZone( TimeZone.getTimeZone( "UTC" ) ); calendar.set( 10 + 1900, 2, 12, 0, 0, 0 ); Date to = calendar.getTime(); Query query = monthQb .range() .onField( "estimatedCreation" ) .ignoreFieldBridge() .andField( "justfortest" ) .ignoreFieldBridge().ignoreAnalyzer() .above( DateTools.round( to, DateTools.Resolution.MINUTE ) ) .createQuery(); helper.assertThat( query ).from( Month.class ).matchesExactlyIds( 2 ); }
@Test public void test() { Team team = new Team( 1 ); team.setName( stringToIndex ); helper.index( team ); if ( unexpectedTokens != null ) { for ( String token : unexpectedTokens ) { String fieldName = "name_" + analyzerName; Query query = new TermQuery( new Term( fieldName, token ) ); helper.assertThat( query ) .as( "Results of searching '" + token + "' on field '" + fieldName + "'" ) .matchesNone(); } } for ( String token : expectedTokens ) { String fieldName = "name_" + analyzerName; Query query = new TermQuery( new Term( fieldName, token ) ); helper.assertThat( query ) .as( "Results of searching '" + token + "' on field '" + fieldName + "'" ) .matchesExactlyIds( team.getId() ); } }
assertRangeQuery( "overriddenFieldName", 1, 3 ).as( "Query id " ).hasResultSize( 3 ); assertRangeQuery( "latitude", -10d, 10d ).as( "Query by double range" ).hasResultSize( 3 ); assertRangeQuery( "importance", (short) 11, (short) 13 ).as( "Query by short range" ).hasResultSize( 3 ); assertRangeQuery( "fallbackImportance", Short.valueOf( "11" ), Short.valueOf( "13" ) ).as( "Query by Short range" ).hasResultSize( 3 ); assertRangeQuery( "popularity", (byte) 21, (byte) 23 ).as( "Query by byte range" ).hasResultSize( 3 ); assertRangeQuery( "fallbackPopularity", Byte.valueOf( "21" ), Byte.valueOf( "23" ) ).as( "Query by Byte range" ).hasResultSize( 3 ); assertRangeQuery( "ranking", 1, 2 ).as( "Query by integer range" ).hasResultSize( 4 ); assertRangeQuery( "myCounter", 1L, 3L ).as( "Query by long range" ).hasResultSize( 3 ); assertRangeQuery( "strMultiple", 0.7d, 0.9d ).as( "Query by multi-fields" ).hasResultSize( 2 ); assertRangeQuery( "visibleStars", -100L, 500L ).as( "Query on custom bridge by range" ).hasResultSize( 4 ); assertRangeQuery( "overriddenFieldName", 1, 3, true, false ).as( "Query by id excluding upper" ).hasResultSize( 2 ); assertRangeQuery( "overriddenFieldName", 1, 3, false, false ).as( "Query by id excluding upper and lower" ).hasResultSize( 1 ); assertRangeQuery( "country.idh", 0.9, 1d ).as( "Range Query for indexed embedded" ).hasResultSize( 2 ); assertRangeQuery( "pinPoints.stars", 4, 5 ).as( "Range Query across entities" ).hasResultSize( 1 ); assertExactQuery( "overriddenFieldName", 1 ).as( "Query id exact" ).matchesExactlyIds( 1 ); assertExactQuery( "latitude", -10d ).as( "Query double exact" ).matchesExactlyIds( 2 ); assertExactQuery( "importance", 12 ).as( "Query short exact" ).matchesExactlyIds( 3 ); assertExactQuery( "popularity", 22 ).as( "Query byte exact" ).matchesExactlyIds( 3 ); assertExactQuery( "longitude", -20d ).as( "Query integer exact" ).matchesExactlyIds( 3 ); assertExactQuery( "myCounter", 4L ).as( "Query long exact" ).matchesExactlyIds( 4 ); assertExactQuery( "strMultiple", 0.1d ).as( "Query multifield exact" ).matchesExactlyIds( 5 ); assertExactQuery( "visibleStars", 1000L ).as( "Query on custom bridge exact" ).matchesExactlyIds( 3 ); assertRangeQuery( "overriddenFieldName", 1, 6 ).as( "Check for deletion on Query" ).hasResultSize( 0 );
.createQuery(); helper.assertThat( query ).from( Month.class ).as( "test slop" ).hasResultSize( 0 ); .createQuery(); helper.assertThat( query ).from( Month.class ).as( "test slop" ).hasResultSize( 1 ); .createQuery(); helper.assertThat( query ).from( Month.class ) .as( "test one term optimization" ) .hasResultSize( 1 );
@Test @TestForIssue(jiraKey = "HSEARCH-2785") public void testPhraseQueryWithNormalizer() throws Exception { final QueryBuilder monthQb = helper.queryBuilder( Month.class ); // Phrase queries on a normalized (non-tokenized) field will only work with single-word queries Query query = monthQb .phrase() .onField( "name" ) .sentence( "February" ) .createQuery(); helper.assertThat( query ).from( Month.class ).hasResultSize( 1 ); query = monthQb .phrase() .onField( "name" ) .sentence( "february" ) .createQuery(); helper.assertThat( query ).from( Month.class ).hasResultSize( 1 ); query = monthQb .phrase() .onField( "mythology_normalized" ) .sentence( "Month whitening" ) .createQuery(); helper.assertThat( query ).from( Month.class ).hasResultSize( 0 ); query = monthQb .phrase() .onField( "mythology_normalized" ) .sentence( "month whitening" ) .createQuery(); helper.assertThat( query ).from( Month.class ).hasResultSize( 0 ); }
.matchesUnorderedIds( 1, 2 ); .from( MyEntity.class ) .matchesExactlyIds( 1 ); .from( AlarmEntity.class ) .matchesNone(); .from( AlarmEntity.class ) .matchesExactlyIds( 2 ); .from( AlarmEntity.class ) .matchesExactlyIds( 2 ); .from( AlarmEntity.class ) .matchesExactlyIds( 2 );
@Test public void testProvidedIdMapping() throws Exception { FullTextSession fullTextSession = Search.getFullTextSession( openSession() ); SearchIntegrator sf = fullTextSession.getSearchFactory().unwrap( SearchIntegrator.class ); ProvidedIdEntry person1 = new ProvidedIdEntry(); person1.setName( "Big Goat" ); person1.setBlurb( "Eats grass" ); ProvidedIdEntry person2 = new ProvidedIdEntry(); person2.setName( "Mini Goat" ); person2.setBlurb( "Eats cheese" ); ProvidedIdEntry person3 = new ProvidedIdEntry(); person3.setName( "Regular goat" ); person3.setBlurb( "Is anorexic" ); SearchITHelper helper = new SearchITHelper( () -> sf ); helper.index() .push( person1, 1 ) .push( person2, 2 ) .push( person3, 3 ) .execute(); Transaction transaction = fullTextSession.beginTransaction(); //we cannot use FTQuery because @ProvidedId does not provide the getter id and Hibernate Hsearch Query extension //needs it. So we use plain HSQuery helper.assertThat( "providedidentry.name", "goat" ) .from( ProvidedIdEntry.class ) .hasResultSize( 3 ); transaction.commit(); getSession().close(); }
@Test @TestForIssue(jiraKey = "HSEARCH-3233") public void testOverridesForField() { final QueryBuilder monthQb = sfHolder.getSearchFactory().buildQueryBuilder().forEntity( Month.class ) .overridesForField( "mythology_ngram", "same_base_as_ngram" ) .get(); // If the analyzer is correctly overridden, only ngram of size 3 should produce results Query query = monthQb.keyword().onField( "mythology_ngram" ).matching( "snowboard" ).createQuery(); helper.assertThat( query ).from( Month.class ).hasResultSize( 0 ); query = monthQb.keyword().onField( "mythology_ngram" ).matching( "snowboar" ).createQuery(); helper.assertThat( query ).from( Month.class ).hasResultSize( 0 ); query = monthQb.keyword().onField( "mythology_ngram" ).matching( "snowboa" ).createQuery(); helper.assertThat( query ).from( Month.class ).hasResultSize( 0 ); query = monthQb.keyword().onField( "mythology_ngram" ).matching( "snowbo" ).createQuery(); helper.assertThat( query ).from( Month.class ).hasResultSize( 0 ); query = monthQb.keyword().onField( "mythology_ngram" ).matching( "snowb" ).createQuery(); helper.assertThat( query ).from( Month.class ).hasResultSize( 0 ); query = monthQb.keyword().onField( "mythology_ngram" ).matching( "snow" ).createQuery(); helper.assertThat( query ).from( Month.class ).hasResultSize( 0 ); query = monthQb.keyword().onField( "mythology_ngram" ).matching( "sno" ).createQuery(); helper.assertThat( query ).from( Month.class ).hasResultSize( 1 ); query = monthQb.keyword().onField( "mythology_ngram" ).matching( "now" ).createQuery(); helper.assertThat( query ).from( Month.class ).hasResultSize( 1 ); query = monthQb.keyword().onField( "mythology_ngram" ).matching( "owb" ).createQuery(); helper.assertThat( query ).from( Month.class ).hasResultSize( 1 ); query = monthQb.keyword().onField( "mythology_ngram" ).matching( "wbo" ).createQuery(); helper.assertThat( query ).from( Month.class ).hasResultSize( 1 ); // etc. }
@Override public void run() { try { String name = "Emmanuel" + index; final Class<?> aClass = MutableFactoryTest.getClassByNumber( index, searchIntegrator.getServiceManager() ); System.err.println( "Creating index #" + index + " for class " + aClass ); searchIntegrator.addClasses( aClass ); Object entity = aClass.getConstructor( Integer.class, String.class ) .newInstance( index, name ); helper.index( entity, index ); EntityIndexBinding indexBindingForEntity = searchIntegrator.getIndexBindings().get( aClass ); assertNotNull( indexBindingForEntity ); Set<IndexManager> indexManagers = indexBindingForEntity.getIndexManagerSelector().all(); assertEquals( 1, indexManagers.size() ); helper.assertThat( "name", "emmanuel" + index ) .from( aClass ) .hasResultSize( 1 ); } catch (ClassNotFoundException | InvocationTargetException | NoSuchMethodException | IllegalAccessException | InstantiationException e) { throw new IllegalStateException( "Unexpected exception while manipulating dynamically created classes", e ); } } }
/** * @param cfg The SearchFactory configuration to be tested * @param fieldName The expected name of the ID field */ private void storeBooksViaProvidedId(SearchConfigurationForTest cfg, String fieldName, boolean matchTitle) { //Should fail right here when @ProvidedId is not enabled: searchIntegrator = integratorResource.create( cfg ); Book book = new Book(); book.title = "Less is nice"; book.text = "When using Infinispan Query, users have to always remember to add @ProvidedId on their classes" + " or a nasty exception will remind them. Can't we just assume it's always annotated?"; String isbn = "some entity-external id"; helper.add( book, isbn ); QueryBuilder queryBuilder = helper.queryBuilder( Book.class ); Query query = queryBuilder.keyword() .onField( fieldName ) .ignoreAnalyzer() .matching( matchTitle ? book.title : isbn ) .createQuery(); helper.assertThat( query ) .from( Book.class ) .hasResultSize( 1 ); }
@Test public void testMultiThreadedAddClasses() throws Exception { searchIntegrator = integratorResource.create( new SearchConfigurationForTest() ); int numberOfClasses = 100; int numberOfThreads = 10; new ConcurrentRunner( numberOfClasses, numberOfThreads, new TaskFactory() { @Override public Runnable createRunnable(int i) throws Exception { return new DoAddClass( i ); } } ) .setTimeout( 1, TimeUnit.MINUTES ) .execute(); for ( int i = 0; i < numberOfClasses; i++ ) { final Class<?> classByNumber = getClassByNumber( i, searchIntegrator.getServiceManager() ); helper.assertThat( "name", "emmanuel" + i ) .from( classByNumber ) .hasResultSize( 1 ); } }
@Test @Category(SkipOnElasticsearch.class) // This only works because of a Lucene-specific hack in org.hibernate.search.bridge.util.impl.NumericFieldUtils.createNumericRangeQuery public void testRangeQueryFromToIgnoreFieldBridge() throws Exception { final QueryBuilder monthQb = helper.queryBuilder( Month.class ); calendar.setTimeZone( TimeZone.getTimeZone( "UTC" ) ); calendar.set( 1900, 2, 12, 0, 0, 0 ); calendar.set( Calendar.MILLISECOND, 0 ); Date from = calendar.getTime(); calendar.set( 1910, 2, 12, 0, 0, 0 ); Date to = calendar.getTime(); Query query = monthQb .range() .onField( "estimatedCreation" ) .ignoreFieldBridge() .andField( "justfortest" ) .ignoreFieldBridge().ignoreAnalyzer() .from( DateTools.round( from, DateTools.Resolution.MINUTE ) ) .to( DateTools.round( to, DateTools.Resolution.MINUTE ) ) .excludeLimit() .createQuery(); helper.assertThat( query ).from( Month.class ).hasResultSize( 1 ); }
@Test @TestForIssue(jiraKey = "HSEARCH-2199") public void testCharFilters() throws Exception { final QueryBuilder monthQb = helper.queryBuilder( Month.class ); //regular query Query query = monthQb.keyword().onField( "htmlDescription" ).matching( "strong" ).createQuery(); helper.assertThat( query ).from( Month.class ).hasResultSize( 2 ); query = monthQb.keyword().onField( "htmlDescription" ).matching( "em" ).createQuery(); helper.assertThat( query ).from( Month.class ).hasResultSize( 2 ); //using the HTMLStripCharFilter query = monthQb.keyword().onField( "htmlDescription_htmlStrip" ).matching( "strong" ).createQuery(); helper.assertThat( query ).from( Month.class ).hasResultSize( 0 ); query = monthQb.keyword().onField( "htmlDescription_htmlStrip" ).matching( "em" ).createQuery(); helper.assertThat( query ).from( Month.class ).hasResultSize( 0 ); query = monthQb.keyword().onField( "htmlDescription_htmlStrip" ).matching( "month" ).createQuery(); helper.assertThat( query ).from( Month.class ).hasResultSize( 3 ); query = monthQb.keyword().onField( "htmlDescription_htmlStrip" ).matching( "spring" ).createQuery(); helper.assertThat( query ).from( Month.class ).hasResultSize( 1 ); query = monthQb.keyword().onField( "htmlDescription_htmlStrip" ).matching( "fake" ).createQuery(); helper.assertThat( query ).from( Month.class ).hasResultSize( 1 ); query = monthQb.keyword().onField( "htmlDescription_htmlStrip" ).matching( "escaped" ).createQuery(); helper.assertThat( query ).from( Month.class ).hasResultSize( 1 ); }
/** * Try to verify that the right analyzer is used when indexing. * * @throws Exception in case the test fails. */ @Test public void testBySearch() throws Exception { SubClass testClass = new SubClass( 1 ); // See https://en.wikipedia.org/wiki/Dotted_and_dotless_I testClass.setName( "I\u0307stanbul" ); helper.index( testClass ); QueryParser parser = new QueryParser( "name", TestConstants.keywordAnalyzer ); org.apache.lucene.search.Query luceneQuery = parser.parse( "name:istanbul" ); helper.assertThat( luceneQuery ) .from( SubClass.class ) .matchesExactlyIds( 1 ); // make sure the result is not always 1 luceneQuery = parser.parse( "name:foo" ); helper.assertThat( luceneQuery ) .from( SubClass.class ) .matchesNone(); }
@Test @TestForIssue(jiraKey = "HSEARCH-2700") public void testBlankQueryString() { QueryBuilder qb = getCoffeeQueryBuilder(); Query query = qb.simpleQueryString() .onFields( "name", "summary", "description" ) .withAndAsDefaultOperator() .matching( " " ) .createQuery(); helper.assertThat( query ).from( Coffee.class ) .sort( new Sort( new SortField( Coffee.NAME_SORT, Type.STRING ) ) ) .matchesNone(); query = qb.simpleQueryString() .onFields( "name", "summary", "description" ) .withAndAsDefaultOperator() .matching( "() (())" ) .createQuery(); helper.assertThat( query ).from( Coffee.class ) .sort( new Sort( new SortField( Coffee.NAME_SORT, Type.STRING ) ) ) .matchesNone(); }
@TestForIssue(jiraKey = "HSEARCH-2545") @Test public void testIndexAndSearchNumericField() { integrator = integratorResource.create( new SearchConfigurationForTest().addClasses( A.class, B.class, C.class ) ); /* * We mainly want to test that the search factory will initialize without error, * but also checking that the field is actually numeric won't hurt. */ A a = new A(); a.id = 0L; B b = new B(); b.id = 1L; b.a = a; C c = new C(); c.id = 2L; c.b = b; helper.add( a, c ); // Range Queries including lower and upper bounds assertRangeQuery( C.class, "b.a.id", a.id, a.id ).as( "Query id " ).hasResultSize( 1 ); }
@Test public void testAddingClassSimpleAPI() throws Exception { searchIntegrator = integratorResource.create( new SearchConfigurationForTest() ); searchIntegrator.addClasses( A.class ); helper.index( new A( 1, "Emmanuel" ), 1 ); helper.assertThat( "name", "emmanuel" ) .from( A.class ) .hasResultSize( 1 ); searchIntegrator.addClasses( B.class, C.class ); helper.index() .push( new B( 1, "Noel" ), 1 ) .push( new C( 1, "Vincent" ), 1 ) .execute(); helper.assertThat( "name", "noel" ) .from( B.class ) .hasResultSize( 1 ); helper.assertThat( "name", "vincent" ) .from( C.class ) .hasResultSize( 1 ); }
@Test public void testRangeQueryFromTo() throws Exception { final QueryBuilder monthQb = helper.queryBuilder( Month.class ); calendar.setTimeZone( TimeZone.getTimeZone( "UTC" ) ); calendar.set( 1900, 2, 12, 0, 0, 0 ); calendar.set( Calendar.MILLISECOND, 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(); helper.assertThat( query ).from( Month.class ).hasResultSize( 1 ); }
@Test public void testTermQueryOnAnalyzer() throws Exception { final QueryBuilder monthQb = helper.queryBuilder( Month.class ); //regular term query Query query = monthQb.keyword().onField( "mythology" ).matching( "cold" ).createQuery(); helper.assertThat( query ).from( Month.class ).hasResultSize( 0 ); //term query based on several words query = monthQb.keyword().onField( "mythology" ).matching( "colder darker" ).createQuery(); helper.assertThat( query ).from( Month.class ).hasResultSize( 1 ); //term query applying the analyzer and generating one term per word query = monthQb.keyword().onField( "mythology_stem" ).matching( "snowboard" ).createQuery(); helper.assertThat( query ).from( Month.class ).hasResultSize( 1 ); //term query applying the analyzer and generating several terms per word query = monthQb.keyword().onField( "mythology_ngram" ).matching( "snobored" ).createQuery(); helper.assertThat( query ).from( Month.class ).hasResultSize( 1 ); //term query not using analyzers query = monthQb.keyword().onField( "mythology" ).ignoreAnalyzer().matching( "Month" ).createQuery(); helper.assertThat( query ).from( Month.class ).hasResultSize( 0 ); }