在將應用程式從 Hibernate Search 5 轉換為 6 的程序中。我已經閱讀了很多檔案,尤其是https://docs.jboss.org/hibernate/search/6.0/migration/html_single/#queries-reference
on如何轉換 Query DSL,我在一個簡單的場景中理解它,但是如何將謂詞嵌套到其他嵌套謂詞中,然后在更大的查詢中將它們與其他謂詞結合起來?
在 Hibernate Search 5 中,我們將使用 queryBuilder.bool() 創建一個 BooleanJunction,然后您可以通過在 bool 上呼叫 createQuery 將其添加到另一個 BooleanJunction 中,并一遍又一遍地創建嵌套謂詞查詢。
我正在談論轉換的代碼型別示例:
BooleanJunction vendorNameBool = queryBuilder.bool();
BooleanJunction nameBool = queryBuilder.bool();
nameBool.must(
qb.keyword()
.onField(CompanyName)
.matching(nameToken1)
.createQuery()
);
nameBool.must(
qb.keyword()
.onField(CompanyName)
.matching(nameToken2)
.createQuery()
);
vendorNameBool.should(nameBool.createQuery);
// do vendorNameBool.should(...) for as many vendor Names that exist, then createQuery
probableVendorNamesQuery = vendorNameBool.createQuery();
// creating a number of Queries from various bools and then combining them:
Query taxIdOrVendorNameOrPhoneNumberQuery = qb.bool()
.should(probableVendorNamesQuery)
.should(taxIdQuery)
.should(phoneNumberQuery)
.createQuery();
//and add to the final BooleanQuery along with other Query pieces
Query idQuery = getIdQuery();
Query fileIdQuery = getFileIdQuery();
BooleanQuery.Builder theQuery = new BooleanQuery.Builder();
theQuery.add(taxIdOrVendorNameOrPhoneNumberQuery, MUST);
theQuery.add(fileIdQuery, MUST);
theQuery.add(idQuery, MUST_NOT);
BooleanQuery probableQuery = theQuery.build();
// add some projections and execute query
大多數 HS6 代碼示例都是 lambda 形式。這里有一個部分提供了一個創建非lamba謂詞的簡單示例,將它們添加到串列中,但是,例如,您如何將該謂詞串列添加到外部should子句,然后添加該should子句,連同另一個應該從句,到外部“必須”從句等等等等?
uj5u.com熱心網友回復:
就個人而言,我只會使用 lambda 語法并嵌套第二個 lambda。改編遷移指南中的示例:
MySearchParameters searchParameters = ...;
SearchSession session = Search.session( entityManager );
List<Book> hits = searchSession.search( Book.class )
.where( f -> f.bool( b -> {
b.must( f.matchAll() );
if ( searchParameters.getSearchTerms() != null ) {
b.must( f.simpleQueryString().fields( "title", "description" )
.matching( searchParameters.getSearchTerms() )
.defaultOperator( BooleanOperator.AND ) );
}
// ...
// BEGIN NEW CODE
SomeComplexParameter complexParam = searchParameters.getSomeComplexParameter();
if ( complexParam != null ) {
b.must( f.bool( b2 -> {
b2.should( f.match().field( "someField1" )
.matching( complexParam.getSomeField1() ) );
b2.should( f.match().field( "someField2" )
.matching( complexParam.getSomeField2() ) );
} ) );
}
// END NEW CODE
} ) )
.fetchHits( params.getPageIndex() * params.getPageSize(), params.getPageSize() );
如果您在編譯時知道子句的數量,您甚至不需要第二個 lambda:
MySearchParameters searchParameters = ...;
SearchSession session = Search.session( entityManager );
List<Book> hits = searchSession.search( Book.class )
.where( f -> f.bool( b -> {
b.must( f.matchAll() );
if ( searchParameters.getSearchTerms() != null ) {
b.must( f.simpleQueryString().fields( "title", "description" )
.matching( searchParameters.getSearchTerms() )
.defaultOperator( BooleanOperator.AND ) );
}
// ...
// BEGIN NEW CODE
SomeComplexParameter complexParam = searchParameters.getSomeComplexParameter();
if ( complexParam != null ) {
b.must( f.bool()
.should( f.match().field( "someField1" )
.matching( complexParam.getSomeField1() ) )
.should( f.match().field( "someField2" )
.matching( complexParam.getSomeField2() ) ) );
}
// END NEW CODE
} ) )
.fetchHits( params.getPageIndex() * params.getPageSize(), params.getPageSize() );
如果您真的不想在頂層使用 lambdas(為什么?),您可以將 lambdas 用于嵌套謂詞,至少:
MySearchParameters searchParameters = ...;
SearchSession session = Search.session( entityManager );
SearchPredicateFactory pf = session.scope( Book.class ).predicate();
List<SearchPredicate> predicates = new ArrayList<>();
if ( searchParameters.getSearchTerms() != null ) {
predicates.add( pf.simpleQueryString().fields( "title", "description" )
.matching( searchParameters.getSearchTerms() )
.defaultOperator( BooleanOperator.AND )
.toPredicate() );
}
// ...
// BEGIN NEW CODE
SomeComplexParameter complexParam = searchParameters.getSomeComplexParameter();
if ( complexParam != null ) {
predicates.add( pf.bool( b -> {
b.should( pf.match().field( "someField1" )
.matching( complexParam.getSomeField1() ) );
b.should( pf.match().field( "someField2" )
.matching( complexParam.getSomeField2() ) );
} )
.toPredicate() );
}
// END NEW CODE
List<Book> hits = searchSession.search( Book.class )
.where( f -> f.bool( b -> {
b.must( f.matchAll() );
for ( SearchPredicate predicate : predicates ) {
b.must( predicate );
}
} )
在這里,只要您事先知道謂詞的數量,就不需要 lambda:
MySearchParameters searchParameters = ...;
SearchSession session = Search.session( entityManager );
SearchPredicateFactory pf = session.scope( Book.class ).predicate();
List<SearchPredicate> predicates = new ArrayList<>();
if ( searchParameters.getSearchTerms() != null ) {
predicates.add( pf.simpleQueryString().fields( "title", "description" )
.matching( searchParameters.getSearchTerms() )
.defaultOperator( BooleanOperator.AND )
.toPredicate() );
}
// ...
// BEGIN NEW CODE
SomeComplexParameter complexParam = searchParameters.getSomeComplexParameter();
if ( complexParam != null ) {
predicates.add( pf.bool()
.should( pf.match().field( "someField1" )
.matching( complexParam.getSomeField1() ) )
.should( pf.match().field( "someField2" )
.matching( complexParam.getSomeField2() ) )
.toPredicate() );
}
// END NEW CODE
List<Book> hits = searchSession.search( Book.class )
.where( f -> f.bool( b -> {
b.must( f.matchAll() );
for ( SearchPredicate predicate : predicates ) {
b.must( predicate );
}
} )
.fetchHits( params.getPageIndex() * params.getPageSize(), params.getPageSize() );
最后,如果你真的想完全遠離 lambdas(但又是為什么?),你可以做這樣的事情。但是請注意,在BooleanPredicateClausesStepHibernate Search 的次要版本中,泛型型別引數可能會發生變化,因此升級時此代碼更有可能中斷。
MySearchParameters searchParameters = ...;
SearchSession session = Search.session( entityManager );
SearchPredicateFactory pf = session.scope( Book.class ).predicate();
BooleanPredicateClausesStep<?> boolStep = pf.bool();
boolStep.must( f.matchAll() );
if ( searchParameters.getSearchTerms() != null ) {
boolStep.must( pf.simpleQueryString().fields( "title", "description" )
.matching( searchParameters.getSearchTerms() )
.defaultOperator( BooleanOperator.AND ) );
}
// ...
SomeComplexParameter complexParam = searchParameters.getSomeComplexParameter();
if ( complexParam != null ) {
BooleanPredicateClausesStep<?> boolStep2 = pf.bool();
boolStep2.should( f.match().field( "someField1" )
.matching( complexParam.getSomeField1() ) );
boolStep2.should( f.match().field( "someField2" )
.matching( complexParam.getSomeField2() ) );
boolStep.must( boolStep2 );
}
SearchPredicate boolPredicate = boolStep.toPredicate();
List<Book> hits = searchSession.search( Book.class )
.where( boolPredicate )
.fetchHits( params.getPageIndex() * params.getPageSize(), params.getPageSize() );
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/445641.html
