如何在嵌入式实体中使用@Facet?

问题描述 投票:0回答:2

我正在尝试从HS 4升级到5但我在分面搜索方面遇到了麻烦。据我所知,@ Facet需要添加在多面字段上,并且已经看过this。但我想要使用的分面字段是嵌入2级,所有我得到的是这个错误:

org.hibernate.search.exception.SearchException: HSEARCH000268: Facet request 'ClientId' tries to facet on  field 'scan.clientGroup.id' which either does not exist or is not configured for faceting (via @Facet). Check your configuration.

我已经在嵌入式实体中尝试过@Facet以多种不同的方式,但似乎没有任何工作 - 我想知道这是如何设置的,谢谢。

hibernate-search
2个回答
1
投票

你在your answer中提到的解决方案是正确的。

另一个解决方案是从孩子到父母有一个@IndexedEmbedded,直接在父id属性上添加@Facet,并在你的分面请求中使用parent.parentId作为字段名称,如the PR I just sent所示。

您的解决方案的主要优点是,如果Parent本身已被索引(如果它有自己的索引),则父级索引不会被不必要的faceting字段污染(与我的解决方案相反)。

您的解决方案的主要缺点是您实质上在实体中的瞬态字段上声明索引字段(JPA意义上的瞬态,即不直接映射到数据库列)。这意味着Hibernate Search无法确定该值何时会发生变化,因此Hibernate Search将禁用某些优化,并且只要Child的属性发生变化,任何属性甚至无关,都会重新索引Child实体。如果您的实体很小,很少更新,或者实例数量有限,那么这可能无关紧要。如果您注意到很多数据库读取似乎没有理由,请记住这一点。


0
投票

我想出了一个解决方案。我不知道这是否是推荐的方式,也许@yrodiere可以发表评论?

基本上只需在根实体上添加一个带有相关@Facet注释的getter方法:

@Indexed
@Entity
public class Child {

...

    @ManyToOne
    @IndexedEmbedded(includeEmbeddedObjectId = true)
    Parent parent;

    @Field(analyze = Analyze.NO)
    @Facet(encoding = FacetEncodingType.STRING)
    public Long getParentId() {
        return parent != null ? parent.getId() : null;
    }
}

然后在查询中:

FullTextQuery fullTextQuery = ftem.createFullTextQuery(luceneQuery);

        FacetingRequest facetingRequest = builder.facet()
                .name("facetRequest")
                .onField("parentId")
                .discrete()
                .orderedBy(FacetSortOrder.COUNT_DESC)
                .includeZeroCounts(false)
                .maxFacetCount(10)
                .createFacetingRequest();

        FacetManager facetManager = fullTextQuery.getFacetManager();
        facetManager.enableFaceting(facetingRequest);

        List<Facet> facets = facetManager.getFacets("facetRequest");

在这种情况下,我还必须将字段编码为字符串,以允许使用离散分面,而不是范围,因为默认情况下它是一个数字字段。

© www.soinside.com 2019 - 2024. All rights reserved.