
org.hibernate.search.bridge.util.impl.NumericFieldUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of hibernate-search-engine Show documentation
Show all versions of hibernate-search-engine Show documentation
Core of the Object/Lucene mapper, query engine and index management
/*
* Hibernate Search, full-text search for your domain model
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or .
*/
package org.hibernate.search.bridge.util.impl;
import java.util.Calendar;
import java.util.Date;
import org.apache.lucene.search.NumericRangeQuery;
import org.apache.lucene.search.Query;
import org.hibernate.search.bridge.FieldBridge;
import org.hibernate.search.bridge.builtin.NumericEncodingDateBridge;
import org.hibernate.search.bridge.builtin.NumericFieldBridge;
import org.hibernate.search.bridge.builtin.impl.NullEncodingTwoWayFieldBridge;
import org.hibernate.search.bridge.builtin.time.impl.NumericTimeBridge;
import org.hibernate.search.bridge.impl.JavaTimeBridgeProvider;
import org.hibernate.search.util.logging.impl.Log;
import org.hibernate.search.util.logging.impl.LoggerFactory;
/**
* Utility class to handle numeric fields.
*
* @author Gustavo Fernandes
* @author Hardy Ferentschik
*/
public final class NumericFieldUtils {
private static final Log log = LoggerFactory.make();
private NumericFieldUtils() {
//not allowed
}
public static Query createNumericRangeQuery(String fieldName, Object from, Object to,
boolean includeLower, boolean includeUpper) {
Class> numericClass;
if ( from != null ) {
numericClass = from.getClass();
}
else if ( to != null ) {
numericClass = to.getClass();
}
else {
throw log.rangeQueryWithNullToAndFromValue( fieldName );
}
if ( Double.class.isAssignableFrom( numericClass ) ) {
return NumericRangeQuery.newDoubleRange( fieldName, (Double) from, (Double) to, includeLower, includeUpper );
}
if ( Byte.class.isAssignableFrom( numericClass ) ) {
return NumericRangeQuery.newIntRange( fieldName, ( (Byte) from ).intValue(), ( (Byte) to ).intValue(), includeLower, includeUpper );
}
if ( Short.class.isAssignableFrom( numericClass ) ) {
return NumericRangeQuery.newIntRange( fieldName, ( (Short) from ).intValue(), ( (Short) to ).intValue(), includeLower, includeUpper );
}
if ( Long.class.isAssignableFrom( numericClass ) ) {
return NumericRangeQuery.newLongRange( fieldName, (Long) from, (Long) to, includeLower, includeUpper );
}
if ( Integer.class.isAssignableFrom( numericClass ) ) {
return NumericRangeQuery.newIntRange( fieldName, (Integer) from, (Integer) to, includeLower, includeUpper );
}
if ( Float.class.isAssignableFrom( numericClass ) ) {
return NumericRangeQuery.newFloatRange( fieldName, (Float) from, (Float) to, includeLower, includeUpper );
}
if ( Date.class.isAssignableFrom( numericClass ) ) {
Long fromValue = from != null ? ((Date) from).getTime() : null;
Long toValue = to != null ? ((Date) to).getTime() : null;
return NumericRangeQuery.newLongRange( fieldName, fromValue, toValue, includeLower, includeUpper );
}
if ( Calendar.class.isAssignableFrom( numericClass ) ) {
Long fromValue = from != null ? ((Calendar) from).getTime().getTime() : null;
Long toValue = to != null ? ((Calendar) to).getTime().getTime() : null;
return NumericRangeQuery.newLongRange( fieldName, fromValue, toValue, includeLower, includeUpper );
}
if ( JavaTimeBridgeProvider.isActive() ) {
if ( java.time.Duration.class.isAssignableFrom( numericClass ) ) {
Long fromValue = from != null ? ( (java.time.Duration) from ).toNanos() : null;
Long toValue = to != null ? ( (java.time.Duration) to ).toNanos() : null;
return NumericRangeQuery.newLongRange( fieldName, fromValue, toValue, includeLower, includeUpper );
}
if ( java.time.Year.class.isAssignableFrom( numericClass ) ) {
Integer fromValue = from != null ? ( (java.time.Year) from ).getValue() : null;
Integer toValue = to != null ? ( (java.time.Year) to ).getValue() : null;
return NumericRangeQuery.newIntRange( fieldName, fromValue, toValue, includeLower, includeUpper );
}
if ( java.time.Instant.class.isAssignableFrom( numericClass ) ) {
Long fromValue = from != null ? ( (java.time.Instant) from ).toEpochMilli() : null;
Long toValue = to != null ? ( (java.time.Instant) to ).toEpochMilli() : null;
return NumericRangeQuery.newLongRange( fieldName, fromValue, toValue, includeLower, includeUpper );
}
}
throw log.numericRangeQueryWithNonNumericToAndFromValues( fieldName );
}
/**
* Will create a {@code RangeQuery} matching exactly the provided value: lower
* and upper value match, and bounds are included. This should perform
* as efficiently as a TermQuery.
*
* @param fieldName the field name the query targets
* @param value the value to match
* @return the created {@code Query}
*/
public static Query createExactMatchQuery(String fieldName, Object value) {
return createNumericRangeQuery( fieldName, value, value, true, true );
}
/**
* When the type of {@code RangeQuery} needs to be guessed among keyword based ranges or numeric based
* range queries, the parameter type defines the strategy.
*
* Note that this is currently only used by the Infinispan backend as a fallback and it should be used with a lot
* of caution as it does not take into account backend specific behaviors.
* For instance, when indexing on Elasticsearch, Dates require a keyword range query.
*
* This should match the default {@code FieldBridge} used for each type.
* @param value on Object
* @return true if the value argument is of any type which is by default indexed as a NumericField
*/
public static boolean requiresNumericRangeQuery(Object value) {
if ( value == null ) {
return false;
}
return value instanceof Double ||
value instanceof Byte ||
value instanceof Short ||
value instanceof Long ||
value instanceof Integer ||
value instanceof Float ||
value instanceof Date ||
value instanceof Calendar ||
( JavaTimeBridgeProvider.isActive() && (
value instanceof java.time.Instant ||
value instanceof java.time.Year ||
value instanceof java.time.Duration
));
}
/**
* Indicates whether the considered {@code FieldBridge} is a numeric one.
*
* @param fieldBridge the considered {@code FieldBridge}
* @return true if the considered {@code FieldBridge} is a numeric {@code FieldBridge}
*/
public static boolean isNumericFieldBridge(FieldBridge fieldBridge) {
if ( fieldBridge instanceof NullEncodingTwoWayFieldBridge ) {
fieldBridge = ( (NullEncodingTwoWayFieldBridge) fieldBridge ).unwrap();
}
return fieldBridge instanceof NumericFieldBridge
|| fieldBridge instanceof NumericTimeBridge
|| fieldBridge instanceof NumericEncodingDateBridge;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy