使用带有编程API(无注释)的Hibernate Search 5.11.3,有没有办法了解添加到类或字段桥中的动态字段?使用MetadataProvidingFieldBridge时,我在FieldMetadataBuilder中看不到任何“构面”配置。
我已经尝试过set()方法中luceneOptions.addSortedDocValuesFieldToDocument()和luceneOptions.addFieldToDocument()的各种组合。这样可以成功更新索引,但是我无法执行构面查询。
我正在尝试做一个基本的属性构面/过滤器,其中有一个具有ID /名称和与产品相关联的属性值的属性通用表。由于各种原因,我正在使用编程API,尤其是对于属性,我无法使用@Facet注释。因此,对于产品,我将此类桥添加到Product.class:
public class ProductClassTagValuesBridge implements FieldBridge
{
@Override
public void set(String name, Object value, Document document, LuceneOptions luceneOptions)
{
Product product = (Product) value;
for (TagValue v : product.getTagValues())
{
Tag tag = v.getTag();
String tagName = "tag-" + tag.getId();
String tagValue = v.getId().toString();
// not sure if this line is required? Have tried with and without
luceneOptions.addFieldToDocument(tagName, tagValue, document);
luceneOptions.addSortedDocValuesFieldToDocument(tagName, tagValue, document);
}
}
}
然后,我构建我的(测试)构面请求以搜索标签56(我确认使用Luke在索引中:)
FacetParameterContext context = queryBuilder.facet()
.name("tag-56")
.onField("tag-56")
.discrete();
FacetingRequest facetingRequest = context.createFacetingRequest();
在search / FacetManager中使用哪个错误:
org.hibernate.search.exception.SearchException:HSEARCH000268:构面请求'TAG_56'尝试在字段'tag-56'上构面,该字段不存在或未配置为构面(通过@Facet)。检查您的配置。
我也尝试过这篇文章中的解决方案中的自定义配置解决方案:Hibernate Search: configure Facet for custom FieldBridge
对于自定义字段,我在产品上的tagValues中添加了一个字段桥。发生相同的错误。
mapping.entity(Product.class).indexed()
.property("tagValues", ElementType.FIELD).field()
.analyze(Analyze.NO).store(Store.YES)
.bridge(ProductTagValuesFieldBridge.class)
简短的回答:休眠搜索尚未允许...。
长回答:
Hibernate Search 5允许使用动态字段,但不允许在自定义网桥中声明的字段上进行构面。也就是说,您可以向索引添加不适合预定义架构的任意值,但不能在这些字段上使用构面。
休眠搜索6允许在自定义网桥中声明的字段上刻面(现在称为“聚合”)(只需将其声明为.aggregable(Aggregable.YES)
,但将其声明为does not allow dynamic fields yet。也就是说,如果您知道启动时的标签列表,能够列出所有标签,并且确定在应用程序启动时它们不会更改,则可以预先声明字段并在其上使用构面。但是,如果您在启动时不知道标签列表,则不可能(目前)。
直到将动态字段添加到Hibernate Search 6中,唯一的解决方案是使用Hibernate Search 5并重新实现自己的构面。如您所料,这将很复杂,您将不得不与Lucene接触。您将必须:
SortedSetDocValuesFacetField
的字段添加到自定义网桥中的文档。FacetsConfig.build
。一种方法(通过黑客攻击)是在您的实体上声明一个虚拟@Facet
字段,即使您不使用它也是如此。IndexReader
对自己进行切面。您可以从休眠搜索IndexReader
中获得as explained here。 org.hibernate.search.query.engine.impl.QueryHits#updateStringFacets
中有一个如何进行构面的示例。