Restricting indexing of embedded entity fields

Consider two indexed entities:

  • Entity A with fields a1 and a2
  • Entity B with fields b1 and @IndexedEmbedded a

The corresponding indexes include the following fields:

  • Index A: a1, a2
  • Index B: b1, a.a1, a.a2

Is it possible to restrict A fields in the B index so that, for example, B will include b1 and a.a1 only?

Unfortunately, @IndexedEmbedded includePaths (and depth) allows restricting the depth only i.e. not the fields the paths refer to.

Not sure I understand why includePaths doesn’t work for you. This:

  • Entity A with fields a1 and a2
  • Entity B with fields b1 and @IndexedEmbedded(includePaths = "a1") a

Should do exactly what you want.

You’re right. The scenario is actually a bit more complex, involving class bridged and spatial fields:

Entity A

@Entity
@Indexed
@ClassBridge(name = "name", impl = ANameBridge.class
@Spatial(name = "coordinates")
public class A ... {
    @Field private String a1;
    @Field private String a2;
    @Transient private String name;
    @Latitude(of = "coordinates") private double latitude;
    @Longitude(of = "coordinates") private double longitude;
    @IndexedEmbedded(depth = 0) private A parent;
}

Entity B

@Entity
@Indexed
public class B ... {
    @Field private String b1;
    @OneToOne
    @IndexedEmbedded(includeEmbeddedObjectId = false, includePaths = { "a1", "parent.a1", "parent.parent.a1" })
    private A a;
}

The indexes look like:

Index A

  • id
  • a1
  • a2
  • name
  • coordinates.lat
  • coordinates.lon

Index B

  • id
  • b1
  • a.a1
  • a.name
  • a.coordinates.lat
  • a.coordinates.lon
  • a.parent.a1
  • a.parent.name
  • a.parent.coordinates.lat
  • a.parent.coordinates.lon
  • a.parent.parent.a1
  • a.parent.parent.name
  • a.parent.parent.coordinates.lat
  • a.parent.parent.coordinates.lon

Include paths is correctly excluding a2 from index B but not (class bridged field) name and (spatial fields) latitude/longitude. The goal would be for index B to look like:

  • id
  • b1
  • a.a1
  • a.parent.a1
  • a.parent.parent.a1

So, it seems class bridges and spatial bridges are indeed applied regardless of the filters applied to your @IndexedEmbedded. I created tickets to solve this: HSEARCH-3212 and HSEARCH-3213.

The problem is mainly that the documentation is unclear about the fact that we only provide this as a performance improvement, ensuring that the given fields are included, but trying to exclude others on a best-effort basis only.

We will not be able to change this in Hibernate Search 5.10, because it would require changes that would very probably break code that relies on this behavior, as it’s been that way for years (probably since @IndexedEmbedded.includePaths was first introduced). Also, we wouldn’t be able to fix it perfectly in Search 5 without some major overhaul, maybe even new APIs.

However, we will solve this in Hibernate Search 6, the next major version.

In the meantime, you can simply ignore this: everything should work fine, you will just have a few extra fields in your index. Which is annoying, but we’re working on it.

Good to know, will certainly be watching those tickets.