Hibernate Search FieldBridge可以为动态字段配置构面吗?

问题描述 投票:1回答:1

使用带有编程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)
java hibernate lucene hibernate-search
1个回答
0
投票

简短的回答:休眠搜索尚未允许...。

长回答:

Hibernate Search 5允许使用动态字段,但不允许在自定义网桥中声明的字段上进行构面。也就是说,您可以向索引添加不适合预定义架构的任意值,但不能在这些字段上使用构面。

休眠搜索6允许在自定义网桥中声明的字段上刻面(现在称为“聚合”)(只需将其声明为.aggregable(Aggregable.YES),但将其声明为does not allow dynamic fields yet。也就是说,如果您知道启动时的标签列表,能够列出所有标签,并且确定在应用程序启动时它们不会更改,则可以预先声明字段并在其上使用构面。但是,如果您在启动时不知道标签列表,则不可能(目前)。

直到将动态字段添加到Hibernate Search 6中,唯一的解决方案是使用Hibernate Search 5并重新实现自己的构面。如您所料,这将很复杂,您将不得不与Lucene接触。您将必须:

  1. 将类型为SortedSetDocValuesFacetField的字段添加到自定义网桥中的文档。
  2. 确保在文档填充后,Hibernate Search在文档上调用FacetsConfig.build。一种方法(通过黑客攻击)是在您的实体上声明一个虚拟@Facet字段,即使您不使用它也是如此。
  3. 完全忽略Hibernate Search的查询功能,并通过IndexReader对自己进行切面。您可以从休眠搜索IndexReader中获得as explained hereorg.hibernate.search.query.engine.impl.QueryHits#updateStringFacets中有一个如何进行构面的示例。
© www.soinside.com 2019 - 2024. All rights reserved.