Hi,
Lucene has different indexes for different data types. In particular, text data and numeric data are indexed completely differently. And querying those completely different indexes requires completely different queries.
QueryParser
creates queries designed to target text fields only. Those queries simply won’t work on numeric fields, whatever you try. When you write age:[4 TO 72]
, QueryParser
interprets that as the age string must be between the string "4" and the string "72"
. An indexed number, any number, cannot match that query, because a number is not a string.
By the way, even string values will match weirdly, because text range queries use lexicographical order: the string “488” would match that query, because it’s after “4” and before “72”.
So, your only solutions:
- Index your numeric fields as strings, and accept the limitations (such as range
[4 TO 72]
matching the string488
). You’ll need to apply a custom value bridge to your numeric fields for that, one that turns numbers into strings. Be aware you have the ability to set the default value bridge for a given type. - Stop using the query parser and switch to the Hibernate Search predicate DSL, which will create the right Lucene queries under the hood, based on the type of your fields. You will lose the ability to pass query strings, though, unless you use the
simpleQueryString
predicate, but it can only target text fields and has more limited syntax thanQueryParser
(no ranges, in particular). - Extend
QueryParser
to correctly deal with numeric fields. For example, you could overrideorg.apache.lucene.queryparser.classic.QueryParserBase#getRangeQuery
to build the range query with the Hibernate SearchPredicate DSL
, which will build a numeric range query for a numeric field. EDIT: You may need to use the Hibernate Searchmetamodel
to determine the expected type of arguments for a given field, and pick the appropriate way to parse the string. Seeorg.hibernate.search.engine.backend.metamodel.IndexValueFieldTypeDescriptor#dslArgumentClass
in particular. - Implement your own query parser that correctly deals with numeric fields. Depending on the syntax you need, and if you use the appropriate tools, this might not be too hard, and might result in more satisfying experience for your end users. You will probably want to use the Hibernate Search
metamodel
to determine the expected type of arguments for a given field and thePredicate DSL
to build search predicates/queries.
If, in Hibernate Search 5, your numeric fields were annotated with @FieldBridge(impl = IntegerBridge.class)
, you were effectively implementing solution 1, but with a built-in bridge instead of a custom one. Indeed, the javadoc of IntegerBridge
states: Bridge an {@link Integer} to a {@link String}
. That built-in bridge’s name was deceptive, which is why it was removed in Hibernate Search 6.