Hibernate 搜索不能在 IndexifEmbedded 上使用聚合

Hibbernate search cannot use agregation on IndexedEmbedded

我正在尝试对@IndexedEmbedded 进行聚合,不幸的是效果不佳,但对同一字段的搜索正常。

我有

Book {
...
@IndexedEmbedded
@ManyToOne
@JoinColumn(name="auth_id")
private Author auth;
...
}

Author {
...
@FullTextField
private String name;
...
}

Search {
...
AggregationKey<Map<String, Long>> countsByAuthKey = AggregationKey.of("countsByAuth");
SearchResult<Book> result = searchSession.search(Book.class).
                            where(f -> f.match().field("title").matching(title).
                            aggregation(countsByAuthKey, f -> f.terms().
                            field("auth.name", String.class)).fetchAll();

...

它在最后一行失败,显示“无法在字段 'auth.name' 上使用 'aggregation:terms'。确保该字段标记为 searchable/sortable/projectable/aggregable”(并且该字段是全文字段)

如错误消息中所述,您没有将该字段标记为可聚合。 reference documentation:

中也提到了这一点

There are a few constraints regarding aggregations. In particular, in order for a field to be "aggregable", it must be marked as such in the mapping, so that it is correctly stored in the index.

事实上,在这种情况下,您不能将字段标记为可聚合:Full-text 字段不能成为聚合的目标。即使 Hibernate Search 允许,这些字段也会被标记化,因此聚合会 return 作者姓名中的每个单词一个桶(例如,一个用于“John”,一个用于“Smith”),这很可能 不是你想要的。

只需在 full-text 字段旁边创建另一个关键字字段。使用 full-text 字段进行搜索,使用关键字字段进行聚合。

Author {
...
@FullTextField
@KeywordField(name = "name_keyword", aggregable = Aggregable.YES)
private String name;
...
}
Search {
...
                            .aggregation(countsByAuthKey, f -> f.terms().
                            field("auth.name_keyword", String.class)).fetchAll();

...
}

在测试之前,请记住您需要 re-create 索引并在映射更改后重新索引数据库。