IndexingDependency on computed field

Hi,

i use hibernate search 6. I would like to search on a computed field that it is calculated by a sql query!

select count from objectA 
inner join objectB on objectB.id = objectA.objectB.id
inner join objectC on objectC.id = objectB.objectC.id
where objectC .name = objectB.name

i have a transient property in my objectA, getCount();

@Transient
@IndexingDependency
@ScaledNumberField(sortable = Sortable.YES)
public BigDecimal getCount() {
	return /*to use the above sql query */;
}

Is it possible with transient property or else ?
thank you !

Hello,

If we’re talking about low-cardinality relationships, I’d recommend doing this in Java:

class ObjectA {
	// ...

	@OneToMany
	private List<ObjectB> objectB = new ArrayList<>();
	
	@Transient
	@IndexingDependency(derivedFrom = {
		@ObjectPath({
			@PropertyValue(propertyName = "objectB"),
			@PropertyValue(propertyName = "count")
		})
	})
	@GenericField(sortable = Sortable.YES)
	public long getCount() {	
		return objectB.stream().mapToLong(ObjectB::getCount).sum();
	}
}
class ObjectB {
	// ...

	@Basic
	private String name;

	@OneToMany
	private List<ObjectC> objectC = new ArrayList<>();
	
	@Transient
	@IndexingDependency(derivedFrom = {
		@ObjectPath({
			@PropertyValue(propertyName = "name")
		}),
		@ObjectPath({
			@PropertyValue(propertyName = "objectC"),
			@PropertyValue(propertyName = "name")
		})
	})
	public long getCount() {
		return objectC.stream().filter(c -> Objects.equal(name, c.getName())).count();
	}
}

If those are high-cardinality relationships, the code above might not perform well enough. If that’s the case, another solution would be to execute a query within a custom bridge, but this will be more complex to set up, especially if you want Hibernate Search to reindex your entities on changes to the objectB/objectC associations or the name properties.

I’d recommend against it, unless you’re comfortable with advanced Hibernate Search usage.

But if you still want that, see:

  • here for the basics of property bridges
  • here for details about declaring the dependencies of your bridge (in your case: objectB.name + objectB.objectC.name)
  • here to get the Hibernate ORM session from a bridge (from there you should be able to execute a query)