Sort and Search by BigInteger primary key

The problem is that the sort order for a BigInteger field is alphanumeric
i have a BigInteger property:

@Id
@Column(name = "id", nullable = false, precision = 18)
@Field(name = "pkid")
@FieldBridge(impl = BigIntegerNumericFieldBridge.class)
private BigInteger id;

In order to fix the sorting I added a custom bridge:

public class BigIntegerNumericFieldBridge implements MetadataProvidingFieldBridge, TwoWayFieldBridge {
	
	private static final BigInteger storeFactor = BigInteger.valueOf(1);
	
	@Override
	public void set(final String name, final Object value, final Document document, final LuceneOptions luceneOptions) {
		if (value != null) {
			final BigInteger integerValue = (BigInteger) value;
			final Long indexedValue = integerValue.multiply(storeFactor).longValue();
			luceneOptions.addNumericFieldToDocument(name, indexedValue, document);
			document.add(new NumericDocValuesField(name, indexedValue));
		}
	}
	
	@Override
	public Object get(final String name, final Document document) {
		final String fromLucene = document.get(name);
		final BigInteger storedBigInteger = new BigInteger(fromLucene);
		return storedBigInteger.divide(storeFactor);
	}
	
	@Override
	public String objectToString(final Object object) {
		return object.toString();
	}
	
	@Override
	public void configureFieldMetadata(final String name, final FieldMetadataBuilder builder) {
		builder.field(name, FieldType.INTEGER).sortable(true);
	}
}

So, the sorting is fixed:

fullTextQuery.setSort(qb.sort().byField(“pkid”).asc().createSort());

But now i have problem with the search

The

qb.keyword().wildcard().onField(“pkid”).matching(“”).createQuery();

gives me the following error
org.hibernate.search.exception.SearchException: HSEARCH000238: Cannot create numeric range query for field ‘pkid’, since values are not numeric (Date, int, long, short or double)

Any ideas? Thanks !

Ideally you would migrate to Hibernate Search 6, which offers first-class support for BigInteger/BigDecimal as (scaled) floating-point values.


If you’re stuck on Hibernate Search 5, however…

Just don’t create a text query when searching on a numeric field.

Change this:

Into this:

qb.keyword().onField(“pkid”)
        .matching(new BigInteger(<your string, obviously not an empty string>).longValue())
        .createQuery();

(That’s considering your store factor is 1; if you change it, you will need to apply a store factor before passing a value to .matching())

Thank you for the quick answer. All works fine now ! :slight_smile: If it is needed to create a wildcard text query with this field (BigInteger id), will it be possible ?
Like something this:

query = qb.keyword().wildcard().onField("pkid")
					.matching("*" + new BigInteger("string").longValue() + "*")
					.createQuery();

No, you cannot run a text query on a numeric field.

If that becomes necessary, just create two separate fields on the same Java property, one numeric and one text:

@Id
@Column(name = "id", nullable = false, precision = 18)
@Field(name = "pkid", bridge = @FieldBridge(impl = BigIntegerNumericFieldBridge.class))
@Field(name = "pkid_text")
private BigInteger id;

Great ! Thank you again ! :smiley: