我正在尝试从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了许多不同的风格,但是似乎没有任何作用-我想知道应该如何设置它,谢谢。
答案 0 :(得分:1)
您在your answer中提到的解决方案是正确的。
另一种解决方案是让@IndexedEmbedded
从子级到父级,直接在父级id属性上添加@Facet
,并在构面请求中使用parent.parentId
作为字段名称,如the PR I just sent所示。
您的解决方案的主要优点是,如果Parent
本身已被索引(如果它具有自己的索引),则父级的索引不会不必要地被构面字段污染(与我的解决方案相反) )。
该解决方案的主要缺点是,您实际上是在实体的瞬态字段上声明一个索引字段(在JPA的意义上是瞬态的,即,不直接映射到数据库列)。这意味着Hibernate Search无法确定何时更改该值,因此,每当Child
的属性发生更改时,Hibernate Search将禁用某些优化并重新索引Child
实体, any 属性,甚至无关。
但是,如果您的实体很小,很少更新或实例数量有限,则这可能无关紧要。请记住这一点,如果您以后发现似乎无缘无故地发现大量数据库读取。
答案 1 :(得分: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");
在这种情况下,我还必须将字段编码为字符串,以允许使用离散构面(而不是范围),因为默认情况下它是数字字段。