gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 05:24:33 24 4
gpt4 key购买 nike

使用 Hibernate Search 5.11.3 和编程 API(无注释),有没有办法对类或字段桥中添加的动态字段进行分面?使用 MetadataProvidingFieldBridge 时,我在 FieldMetadataBuilder 中看不到任何可用的“facet”配置。

我在 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);
}
}
}

然后我构建我的(测试)分面请求来搜索 tag-56(我使用 Luke 确认它位于索引中):

FacetParameterContext context = queryBuilder.facet()
.name("tag-56")
.onField("tag-56")
.discrete();

FacetingRequest facetingRequest = context.createFacetingRequest();

在搜索/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 还不允许这样做。

长答案:

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

Hibernate 搜索 6 允许在自定义桥中声明的字段上进行分面(现在称为“聚合”)(只需将它们声明为 .aggregable(Aggregable.YES)),但是 does not allow dynamic fields yet

编辑:从 6.0.0.Beta7 开始,通过字段模板支持动态字段。所以我剩下的信息不再有用了。请参阅this section of the documentation有关字段模板的更多信息。完全有可能在您的桥中声明一个可聚合的动态字段。

<小时/>

有关在没有动态字段的情况下工作的方法的原始消息(已过时):

也就是说,如果您在启动时知道标签列表,能够列出所有标签,并且确定它们在应用程序启动时不会更改,则可以预先声明字段并在它们上使用分面。但是,如果您在启动时不知道标签列表,那么这一切(目前)都是不可能的。

在将动态字段添加到 Hibernate Search 6 之前,唯一的解决方案是使用 Hibernate Search 5 并自行重新实现分面。正如您所预料的,这将很复杂,并且您必须亲自动手使用 Lucene。您必须:

  1. SortedSetDocValuesFacetField 类型的字段添加到自定义桥中的文档。
  2. 确保 Hibernate Search 在填充文档后调用 FacetsConfig.build。实现此目的的一种方法(通过黑客)是在您的实体上声明一个虚拟 @Facet 字段,即使您不使用它。
  3. 完全忽略 Hibernate Search 的查询功能并通过 IndexReader 自行执行分面。您可以从 Hibernate Search as explained here 获取 IndexReaderorg.hibernate.search.query.engine.impl.QueryHits#updateStringFacets 中提供了如何执行分面的示例。

关于java - Hibernate Search FieldBridge 可以为动态字段配置构面吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58922827/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com