Tony
February 7, 2023, 9:40am
1
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)