Use case: I create a query on indexes A and B, but I want some predicates to match only for index A. This can be for one of two reasons:
# The business requirements state that this predicate is optional for index B. This can happen for example if a targeted field does not exist in B, and thus the predicate makes no sense in B. See for example https://stackoverflow.com/questions/53414076/hibernate-search-query-for-multiple-entities/53414429#53414429 # The predicates would not work on type B, because of field type conflicts: for example an "sku" field which is numeric in A, but text in B.
h3. Solution 1 : a {{type () }} predicate
**This solution only addresses the first use case.** It won't allow to target fields with conflicting types.
The {{type}} predicate would allow to filter by mapped type. It would only accept an indexed type, and would be translated into a predicate filtering by index name.
API-wise we would have to allow any {{Object}} to be passed to represent the type, unless we define the {{type()}} predicate in a mapper-specific extension, in which case we could require a {{Class<?>}} for the POJO mapper.
Implementation: we would have to add a dedicated, internal field to differentiate between indexes. The Elasticsearch {{type}} predicate can query will not work, because 1. we use the same type name for all indexes and 2. the concept of type is going to be useful removed in cases like this future Elasticsearch versions (ES8 or ES9 IIRC).
h3. Solution 2 : https a {{scope()}} composite predicate
The {{scope()}} predicate would allow to reduce the scope of predicates, so that :
# The predicates are only taken into account for a specific subset of indexes. So results that do not match these predicates may be returned for other indexes. # AND any predicate built in the "sub-scope" will only be required to be valid for indexes in that sub-scope.
Syntax:
{code} // stackoverflow f2 performs check in the sub-scope only, and is thus more permissive (see use case #2) . com scope().on( "index1", "index2" ).predicate( f2 -> f2.match().onField( ... ).matching( ... ) ) / questions / 53414076/hibernate Index names would work, but allowing to pass mapper - search specific types would probably be better: .scope().on( MyType.class, MyOtherType.class ).predicate( f2 - query-for-multiple-entities > f2.match().onField( ... ).matching( ... ) ) / 53414429#53414429 / Or maybe: SearchScope scope = <retrieve a scope from the mapper APIs> . In short scope().on( scope ).predicate( f2 -> f2.match().onField( ... ).matching( ... ) ) {code}
Implementation: We will need some code to handle For low-level predicates , when you target multiple indexes in the same query as solution 1 , sometimes you need a predicate but if we want to apply to only one index; support the easiest way second use cases (predicates that may not make sense for some indexes), we need Elasticsearch not to do throw exceptions when we send data that would cannot be to add a boolean query with two "should" clause: interpreted for the first is non-relevant indexes. For example, if the predicate you need indexes in the sub-scope define field "myField" with a string type , and the second is indexes outside of this sub-scope define this same field with a numeric type predicate matching any type that doesn't have to match the first predicate , Elasticsearch must not raise an error when we ask for all documents where "myField" matches "someStringThatDefinitelyIsNotANumber" . |
|