I’m trying to migrate my search queries from Hibernate Search 5 to 6 while using Lucene.
There are few components I made:
- SearchRequest POJO that holds all the data needed for single search request
- SearchService which manages all searches for my project
- many util classes that creates tiny Query objects that are later linked by BooleanJunction into the main query
Is there any chance to do similar with Hibernate Search 6?
I’m really lost with all those new classes and syntax and I just don’t know how to convert.
Few code snippets to get idea what I’m using while building my search query:
@Builder
class SearchReq {
private String q;
private Integer categoryId;
private Integer manufacturerId;
private Integer manufacturerName;
private Integer providerId;
private Integer providerName;
private Integer countryId;
private Integer cityId;
private Integer tagId;
// ... etc.
private Integer pageSize;
private Integer page;
private String sortField;
}
Creating search request:
SearchReq.builder().q("tofu").cityId(12).build();
Properties holding NULL are skipped, so in this case you’d get everything that contains “tofu” and is available in city with ID == 12.
Once I have POJO filled up, I can create list of tiny queryies that will be later joined.
final List<Query> queries = new LinkedList<>();
if( q != null ) { queries.add( QueryUtil.byQ( q ) ); }
if( categoryId != null ) { queries.add( QueryUtil.byCategoryId( categoryId ) ); }
// etc.
QueryUtil.java
private static Query byCategoryId(final QueryBuilder queryBuilder, final Integer categoryId) {
return queryBuilder.createBooleanQuery("category", categoryId);
}
Another step is to apply boosting factors:
public static void article(final QueryBuilder queryBuilder, final String searchTerm, final BooleanJunction<?> bj) {
bj.should(QueryForField.q(SearchField.NAME, searchTerm, queryBuilder)).boostedTo(SearchField.NAME.getBoostFactor());
bj.should(QueryForField.q(SearchField.SHORT_NAME, searchTerm, queryBuilder)).boostedTo(SearchField.SHORT_NAME.getBoostFactor());
bj.should(QueryForField.q(SearchField.DESCRIPTION, searchTerm, queryBuilder)).boostedTo(SearchField.DESCRIPTION.getBoostFactor());
bj.should(QueryForField.q(SearchField.SEARCH_AID, searchTerm, queryBuilder)).boostedTo(SearchField.SEARCH_AID.getBoostFactor());
bj.should(QueryForField.q(SearchField.MANUFACTURER, searchTerm, queryBuilder)).boostedTo(SearchField.MANUFACTURER.getBoostFactor());
bj.should(QueryForField.q(SearchField.PRICE_INFOS, searchTerm, queryBuilder)).boostedTo(SearchField.PRICE_INFOS.getBoostFactor());
bj.should(QueryForField.q(SearchField.CATEGORIES, searchTerm, queryBuilder)).boostedTo(SearchField.CATEGORIES.getBoostFactor());
bj.should(QueryForField.q(SearchField.TAGS, searchTerm, queryBuilder)).boostedTo(SearchField.TAGS.getBoostFactor());
}
Finally I join all the queries into main query:
final BooleanJunction<?> master = queryBuilder.bool();
queries.stream().filter(Objects::nonNull).forEach(master::must);
final Query theQuery = master.createQuery();