Yoann Rodière (
https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=557058%...
) *commented* on HSEARCH-3325 (
https://hibernate.atlassian.net/browse/HSEARCH-3325?atlOrigin=eyJpIjoiODV...
)
Re: Search 6 groundwork - Restore support for full-text filters (
https://hibernate.atlassian.net/browse/HSEARCH-3325?atlOrigin=eyJpIjoiODV...
)
I can conceive that a feature that was present in Search 5 would still be useful in Search
6. However, the feature as you implemented it is not the same as the one that was present
in Search 5:
* In Search 5, filters were applied *after* the query was built, as some kind of
"mask", which was useful in particular for aspect-oriented programming (and
incidentally caused the query to be mutable, which is not something we want in 6).
* In Search 5, there was no magic around the filter reference that would associate a
filter to a single field ("prices.is-shared" contains both the field name and
the filter name)
* In Search 5, the value of filters arguments was defined exclusively when applying a
filter, not when defining the filter using the @FullTextFilterDef annotation.
* In Search 5, filters used to be cached, which doesn't seem useful in your case.
* And so on.
My point is, this is not the same feature as in Search 5. Thus, we can't just say
"there was this feature in Search 5, we need to merge this patch". You're
proposing essentially a new feature, or at least a heavily revamped feature, and I need to
understand the use case.
And whether it is useful for someone should be left to the end user
True... let me put it another way: I need to know there is something you cannot achieve
without this feature, or at least that would be complicated or time-consuming to achieve
without this feature. I need to know there is value in this feature. Sometimes I can see
it clearly, but here I need your help to understand.
You have to understand that even when you provide the code of a new feature, there is a
cost for the maintainers. First when merging it to make sure everything is well tested and
documented, and fix the code where appropriate, and later to keep the feature in working
order when we modify some code it uses.
For the record, I spent more than one week, full-time, just testing, fixing and
documenting your other PR about multi-valued sorts. That was time well spent, because I
knew the feature is very useful. But still, that's a lot of time, and I cannot spend
all my time on features without any idea of their value.
It's about simplifying your queries
Alright. Then I ask you, honestly: in what ways do you feel the code you gave is simpler
than this, which doesn't require any additional API :
private class BeansDataModel extends SearchDataModel<Assortment> {
@Override
public SearchQuery<Assortment> search(List<SortMeta> multiSortMeta,
Map< String , Object > filters) {
try {
SearchSession session = Search.session(em);
SearchScope<Assortment> scope = session.scope(Assortment.class);
SearchSortFactory sorter = scope.sort();
CompositeSortComponentsStep sort = sorter.composite();
SearchPredicateFactory spf = scope.predicate();
BooleanPredicateClausesStep pricesFilter = spf.bool()
.filter(isPriceActive(scope))
.filter(isPriceShared(scope, identity.getAccount()));
sort.add(sorter.field( "prices.bruttoPrice_sort" )
.asc()
.mode(MultiValue.MIN)
.filter(pricesFilter));
for (SortMeta sortMeta : multiSortMeta) {
String fieldName = sortMeta.getSortField();
switch (sortMeta.getSortOrder()) {
case ASCENDING:
sort.add(sorter.field(fieldName).asc());
break ;
case DESCENDING:
sort.add(sorter.field(fieldName).desc());
break ;
}
}
PredicateFinalStep select;
if (searchFullText != null ) {
select = scope.predicate().simpleQueryString()
.field( "shoppingName" ).boost(0.5f)
.matching(searchFullText);
} else {
select = scope.predicate()
.matchAll();
}
SearchQuery<Assortment> query = session.search(scope)
.where((f) -> f.bool().must(select)
.filter(f.nested()
.objectField( "prices" )
.nest(pricesFilter)
)).sort(sort.toSort()).toQuery();
return query;
} catch (Exception ex) {
throw new IllegalStateException(ex);
}
}
}
private static SearchPredicate isPriceActive(SearchScope scope) {
return PermissionsFilterFactory.create(scope, "prices" );
}
private static SearchPredicate isPriceShared(SearchScope scope, Account user) {
return PricesActiveFilterFactory.create(scope, "prices.sharings" , user,
"share" );
}
@Entity(name = "Assortment" )
public class Assortment {
....
@IndexedEmbedded(storage = ObjectFieldStorage.NESTED)
@OneToMany(mappedBy = "assortment" , orphanRemoval = true , fetch =
FetchType.EAGER, cascade = CascadeType.ALL)
private List<AssortmentPrice> prices = new ArrayList<>();
...
@Entity(name = "AssortmentPrice" )
public class AssortmentPrice implements Serializable {
....
@FullTextField(analyzer = "permission" )
@Convert(converter = PermissionsConverter.class)
@Column(name = "Sharings" , length = 2048)
private Permissions sharings = new Permissions();
@GenericField
@Column(name = "Active" )
private boolean active = true ;
}
public class PermissionsFilterFactory {
public SearchPredicate create(SearchScope scope, String fieldPath, Account user, String
operation) {
SearchPredicate filter;
SearchPredicateFactory predicate = scope.predicate();
if (operation == null ) {
operation = "read" ;
}
PermissionQuery query = new PermissionQuery(fieldPath, operation, user);
filter = predicate.extension(LuceneExtension.get())
.fromLuceneQuery(query)
.toPredicate();
return filter;
}
}
public class PricesActiveFilterFactory {
@Override
public SearchPredicate create(SearchScope scope, String fieldPath) {
SearchPredicate filter;
filter = ctx.predicate()
.match().field(fieldPath)
.matching( true )
.toPredicate();
return filter;
}
}
(
https://hibernate.atlassian.net/browse/HSEARCH-3325#add-comment?atlOrigin...
) Add Comment (
https://hibernate.atlassian.net/browse/HSEARCH-3325#add-comment?atlOrigin...
)
Get Jira notifications on your phone! Download the Jira Cloud app for Android (
https://play.google.com/store/apps/details?id=com.atlassian.android.jira....
) or iOS (
https://itunes.apple.com/app/apple-store/id1006972087?pt=696495&ct=Em...
) This message was sent by Atlassian Jira (v1001.0.0-SNAPSHOT#100122- sha1:87fe5bb )