Сначала индексируйте id категорий:
@Entity
@Indexed
public class Product {
private long id;
@Field
private String title;
@IndexedEmbedded
private Category category;
}
@Entity
public class Category {
@Field // Added this
private long id;
@Field
private String name;
}
Затем обязательно переиндексируйте данные, например, с помощью индексатора массы .
Затем,измените код запроса, как описано ниже.
Сначала вам понадобится SQL IN, который выражается в мире Lucene как category.id = <first> OR category.id = <second> OR ...
.Только логические операторы немного отличаются от того, к чему вы привыкли ( см. Здесь );в вашем случае вы хотите, чтобы «хотя бы одно» предложение совпадало, поэтому вам придется использовать оператор should
:
List<Long> categoryIds = ...; // Provided by the user
BooleanJunction<?> categoryIdJunction = queryBuilder.bool();
for ( categoryId : categoryIds ) {
categoryIdJunction.should(
queryBuilder
.keyword()
.onField("category.id")
.matching(categoryId)
.createQuery();
);
}
org.apache.lucene.search.Query categoryIdQuery = categoryIdJunction.createQuery();
Наконец, вам нужно будет объединить этот запрос с другим запросом наназвание.Для этого используйте другое логическое соединение, на этот раз с оператором must
(все предложения должны совпадать):
org.apache.lucene.search.Query titleQuery = queryBuilder
.keyword()
.onField("title")
.matching(queryString)
.createQuery();
org.apache.lucene.search.Query luceneQuery = queryBuilder.bool()
.must( categoryIdQuery )
.must( titleQuery )
.createQuery();