@Override public List<Book> searchByMedium(String terms, BookMedium medium, int offset, int limit) { FullTextQuery<Book> query = entityManager.search( Book.class ).query() .asEntity() .predicate( f -> f.bool( b -> { if ( terms != null && !terms.isEmpty() ) { b.must( f.match() .onField( "title" ).boostedTo( 2.0f ) .orField( "summary" ) .matching( terms ) ); } b.must( f.nested().onObjectField( "copies" ) .nest( f.match().onField( "copies.medium" ).matching( medium ) ) ); } ) ) .sort( b -> b.byField( "title_sort" ) ) .build(); query.setFirstResult( offset ); query.setMaxResults( limit ); return query.getResultList(); }
/** * Target the given field in the match predicate, * as an alternative to the already-targeted fields. * <p> * See {@link MatchPredicateContext#onField(String)} for more information on targeted fields. * * @param absoluteFieldPath The absolute path (from the document root) of the targeted field. * @return {@code this}, for method chaining. * * @see MatchPredicateContext#onField(String) */ default MatchPredicateFieldSetContext orField(String absoluteFieldPath) { return orFields( absoluteFieldPath ); }
public SearchPredicate extendedPredicate(String fieldName, String value) { return delegate.match().onField( fieldName ).matching( value ).toPredicate(); } }
.asReference() .predicate( f -> f.match().onField( indexMapping.string1Field.relativeFieldName ) .orField( indexMapping.string2Field.relativeFieldName ) .matching( indexMapping.string1Field.document1Value.indexedValue ) .toPredicate() .asReference() .predicate( f -> f.match().onField( indexMapping.string1Field.relativeFieldName ) .orField( indexMapping.string2Field.relativeFieldName ) .matching( indexMapping.string2Field.document1Value.indexedValue ) .toPredicate() .asReference() .predicate( f -> f.match().onField( indexMapping.string1Field.relativeFieldName ) .orFields( indexMapping.string2Field.relativeFieldName, indexMapping.string3Field.relativeFieldName ) .matching( indexMapping.string1Field.document1Value.indexedValue ) .toPredicate() .asReference() .predicate( f -> f.match().onField( indexMapping.string1Field.relativeFieldName ) .orFields( indexMapping.string2Field.relativeFieldName, indexMapping.string3Field.relativeFieldName ) .matching( indexMapping.string2Field.document1Value.indexedValue ) .toPredicate() .asReference() .predicate( f -> f.match().onField( indexMapping.string1Field.relativeFieldName ) .orFields( indexMapping.string2Field.relativeFieldName, indexMapping.string3Field.relativeFieldName ) .matching( indexMapping.string3Field.document1Value.indexedValue ) .toPredicate()
.predicate( root -> root.bool() .should( c -> c.match().onField( indexMapping.string1Field.relativeFieldName ) .matching( indexMapping.string1Field.document1Value.indexedValue ).toPredicate() .should( c -> c.match().onField( indexMapping.string1Field.relativeFieldName ).boostedTo( 42 ) .matching( indexMapping.string1Field.document3Value.indexedValue ).toPredicate() .asReference() .predicate( root -> root.bool() .should( c -> c.match().onField( indexMapping.string1Field.relativeFieldName ).boostedTo( 42 ) .matching( indexMapping.string1Field.document1Value.indexedValue ).toPredicate() .matching( indexMapping.string1Field.document3Value.indexedValue ).toPredicate()
@Test public void queryWrapper() { StubMappingSearchTarget searchTarget = indexManager.createSearchTarget(); QueryWrapper queryWrapper = searchTarget.query() .asReference( QueryWrapper::new ) .predicate( f -> f.match().onField( "string" ).matching( "platypus" ).toPredicate() ) .build(); assertThat( queryWrapper.query.getQueryString() ).contains( "platypus" ); }
@Test public void boost() { StubMappingSearchTarget searchTarget = indexManager.createSearchTarget(); SearchQuery<DocumentReference> query = searchTarget.query() .asReference() .predicate( f -> f.bool() .should( f.spatial().within().onField( "geoPoint" ).boundingBox( CHEZ_MARGOTTE_BOUNDING_BOX ) ) .should( f.match().onField( "string" ).boostedTo( 42 ).matching( OURSON_QUI_BOIT_STRING ) ) .toPredicate() ) .sort( c -> c.byScore() ) .build(); assertThat( query ) .hasDocRefHitsExactOrder( INDEX_NAME, OURSON_QUI_BOIT_ID, CHEZ_MARGOTTE_ID ); query = searchTarget.query() .asReference() .predicate( f -> f.bool() .should( f.spatial().within().onField( "geoPoint" ).boostedTo( 42 ).boundingBox( CHEZ_MARGOTTE_BOUNDING_BOX ) ) .should( f.match().onField( "string" ).matching( OURSON_QUI_BOIT_STRING ) ) .toPredicate() ) .sort( c -> c.byScore() ) .build(); assertThat( query ) .hasDocRefHitsExactOrder( INDEX_NAME, CHEZ_MARGOTTE_ID, OURSON_QUI_BOIT_ID ); }
@Test public void getQueryString() { StubMappingSearchTarget searchTarget = indexManager.createSearchTarget(); SearchQuery<DocumentReference> query = searchTarget.query() .asReference() .predicate( f -> f.match().onField( "string" ).matching( "platypus" ).toPredicate() ) .build(); assertThat( query.getQueryString() ).contains( "platypus" ); }
@Override public List<Book> searchByMedium(String terms, BookMedium medium, int offset, int limit) { FullTextSearchTarget<Book> target = entityManager.search( Book.class ); BooleanJunctionPredicateContext booleanBuilder = target.predicate().bool(); if ( terms != null && !terms.isEmpty() ) { booleanBuilder.must( target.predicate().match() .onField( "title" ).boostedTo( 2.0f ) .orField( "summary" ) .matching( terms ) ); } booleanBuilder.must( target.predicate().nested().onObjectField( "copies" ) .nest( target.predicate().match().onField( "copies.medium" ).matching( medium ) ) ); FullTextQuery<Book> query = entityManager.search( Book.class ).query() .asEntity() .predicate( booleanBuilder.toPredicate() ) .sort( target.sort().byField( "title_sort" ).toSort() ) .build(); query.setFirstResult( offset ); query.setMaxResults( limit ); return query.getResultList(); }
@Test public void boost() { StubMappingSearchTarget searchTarget = indexManager.createSearchTarget(); SearchQuery<DocumentReference> query = searchTarget.query() .asReference() .predicate( f -> f.bool() .should( f.spatial().within().onField( "geoPoint" ).polygon( CHEZ_MARGOTTE_POLYGON ) ) .should( f.match().onField( "string" ).boostedTo( 42 ).matching( OURSON_QUI_BOIT_STRING ) ) .toPredicate() ) .sort( c -> c.byScore() ) .build(); assertThat( query ) .hasDocRefHitsExactOrder( INDEX_NAME, OURSON_QUI_BOIT_ID, CHEZ_MARGOTTE_ID ); query = searchTarget.query() .asReference() .predicate( f -> f.bool() .should( f.spatial().within().onField( "geoPoint" ).boostedTo( 42 ).polygon( CHEZ_MARGOTTE_POLYGON ) ) .should( f.match().onField( "string" ).matching( OURSON_QUI_BOIT_STRING ) ) .toPredicate() ) .sort( c -> c.byScore() ) .build(); assertThat( query ) .hasDocRefHitsExactOrder( INDEX_NAME, CHEZ_MARGOTTE_ID, OURSON_QUI_BOIT_ID ); }
/** * Target the given field in the match predicate, * as an alternative to the already-targeted fields. * <p> * See {@link MatchPredicateContext#onField(String)} for more information on targeted fields. * * @param absoluteFieldPath The absolute path (from the document root) of the targeted field. * @return {@code this}, for method chaining. * * @see MatchPredicateContext#onField(String) */ default MatchPredicateFieldSetContext orField(String absoluteFieldPath) { return orFields( absoluteFieldPath ); }
@Test public void error_invalidType() { StubMappingSearchTarget searchTarget = indexManager.createSearchTarget(); List<ByTypeFieldModel<?>> fieldModels = new ArrayList<>(); fieldModels.addAll( indexMapping.supportedFieldModels ); fieldModels.addAll( indexMapping.supportedFieldWithDslConverterModels ); for ( ByTypeFieldModel<?> fieldModel : fieldModels ) { String absoluteFieldPath = fieldModel.relativeFieldName; Object invalidValueToMatch = new InvalidType(); SubTest.expectException( "match() predicate with invalid parameter type on field " + absoluteFieldPath, () -> searchTarget.predicate().match().onField( absoluteFieldPath ).matching( invalidValueToMatch ) ) .assertThrown() .isInstanceOf( SearchException.class ) .hasMessageContaining( "Unable to convert DSL parameter: " ) .hasMessageContaining( InvalidType.class.getName() ) .hasCauseInstanceOf( ClassCastException.class ) .satisfies( FailureReportUtils.hasContext( EventContexts.fromIndexFieldAbsolutePath( absoluteFieldPath ) ) ); } }
@Override public Optional<Book> getByIsbn(String isbnAsString) { if ( isbnAsString == null ) { return Optional.empty(); } // Must use Hibernate ORM types (as opposed to JPA types) to benefit from query.uniqueResult() FullTextSession fullTextSession = entityManager.unwrap( FullTextSession.class ); org.hibernate.search.mapper.orm.hibernate.FullTextQuery<Book> query = fullTextSession.search( Book.class ).query() .asEntity() // TODO allow to bypass the bridge in the DSL .predicate( f -> f.match().onField( "isbn" ).matching( new ISBN( isbnAsString ) ).toPredicate() ) .build(); return Optional.ofNullable( query.uniqueResult() ); }
@Test public void should_mustNot() { StubMappingSearchTarget searchTarget = indexManager.createSearchTarget(); SearchQuery<DocumentReference> query = searchTarget.query() .asReference() .predicate( f -> f.bool() .should( f.match().onField( "field1" ).matching( FIELD1_VALUE1 ) ) .should( f.match().onField( "field1" ).matching( FIELD1_VALUE3 ) ) .mustNot( f.match().onField( "field1" ).matching( FIELD1_VALUE1 ) ) .toPredicate() ) .build(); assertThat( query ) .hasDocRefHitsAnyOrder( INDEX_NAME, DOCUMENT_3 ); }
@Override public Optional<Book> getByIsbn(String isbnAsString) { if ( isbnAsString == null ) { return Optional.empty(); } // Must use Hibernate ORM types (as opposed to JPA types) to benefit from query.uniqueResult() FullTextSession fullTextSession = entityManager.unwrap( FullTextSession.class ); org.hibernate.search.mapper.orm.hibernate.FullTextSearchTarget<Book> target = fullTextSession.search( Book.class ); org.hibernate.search.mapper.orm.hibernate.FullTextQuery<Book> query = target.query() .asEntity() .predicate( // TODO allow to bypass the bridge in the DSL target.predicate().match().onField( "isbn" ).matching( new ISBN( isbnAsString ) ).toPredicate() ) .build(); return Optional.ofNullable( query.uniqueResult() ); }
.asReference() .predicate( f -> f.bool() .mustNot( f.match().onField( "field1" ).matching( FIELD1_VALUE2 ) ) .mustNot( f.match().onField( "field1" ).matching( FIELD1_VALUE3 ) ) .should( f.match().onField( "field2" ).matching( FIELD2_VALUE2 ) ) .should( f.match().onField( "field3" ).matching( FIELD3_VALUE3 ) ) .toPredicate() .asReference() .predicate( f -> f.bool() .mustNot( f.match().onField( "field1" ).matching( FIELD1_VALUE1 ) ) .mustNot( f.match().onField( "field1" ).matching( FIELD1_VALUE3 ) ) .should( f.match().onField( "field2" ).matching( FIELD2_VALUE2 ) ) .should( f.match().onField( "field3" ).matching( FIELD3_VALUE3 ) ) .toPredicate()