Associated entities each have their own Lucene index, and also store some data in each other's indexes. With embedded objects, search information is stored exclusively in the containing entity's index.
However, bear in mind that these classes may be associated or embedded in more than one place. For example, if you had the Customer
and Publisher
entities in your data model, both of them might have an embedded object of type Address
.
Normally, we use the @Field
annotation to tell Hibernate Search which fields should be indexed and searchable. However, what if we want this to vary with associated or embedded objects? What if we want a field to be indexed, or not indexed, depending on which other entity contains it? Hibernate Search provides this ability through an optional element in the @IndexedEmbedded
annotation. This includePaths
element indicates that within the Lucene index for this containing entity, only certain fields of the associated entity or embedded object should be included.
In our example application, the CustomerReview
class has both its username
and comments
variable annotated as searchable fields. However, let's say that for the customerReviews
embedded within App
, we only care about searching on comments. The change to App
looks like this:
...
@ElementCollection(fetch=FetchType.EAGER)
@Fetch(FetchMode.SELECT)
@IndexedEmbedded(depth=1, includePaths = { "comments" })
private Set<CustomerReview>customerReviews;
...
Even though CustomerReview.username
is annotated with @Field
, that field will not be added to the Lucene index for App
. This saves space, and improves performance by not making Lucene work hard on unnecessary indexing. The only trade-off is that to prevent errors, we must remember to avoid using any non-included fields in our query code.