我正在尝试使用 Elasticsearch 后端从 Hibernate 5 切换到 Hibernate 6。 在我们的项目中,有一个具有动态字段数的实体。据我了解,处理此问题的最佳方法是使用带有模板的动态字段,如此处所述https://docs.jboss.org/hibernate/search/6.2/reference/en-US/html_single/#bridge-index -field-dsl-dynamic
我创建了一个属性绑定器来将动态字段添加到索引中。这很好用,字段被添加到索引中并且可以被搜索。现在的问题是如何对这些字段进行排序?我收到错误:org.hibernate.search.util.common.SearchException: HSEARCH000610: Unknown field 'customFields.town_TextForSort.keyword'.
属性绑定器包含以下代码:
IndexSchemaObjectField customFields = schemaElement
.objectField( "customFields", ObjectStructure.FLATTENED)
.multiValued();
customFields.fieldTemplate(
"fieldValueTemplate_TextDefault",
f -> f.asString()
.analyzer("customAnalyzer")
.searchable( Searchable.YES )
.sortable(Sortable.NO)
)
.matchingPathGlob( "*_TextDefault" );
customFields.fieldTemplate(
"fieldValueTemplate_TextForSort",
f -> f.asString()
.normalizer("customNormalizer")
.sortable( Sortable.YES )
.searchable( Searchable.NO )
)
.matchingPathGlob( "*_TextForSort" );
新字段像这样添加到索引中:
"town_TextDefault": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"town_TextForSort": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
使用路径“customFields.town_TextForSort”进行排序不是一个好主意,因为它是“文本”类型而不是“关键字”类型。 使用路径“customFields.town_TextForSort.keyword”进行排序不起作用,因为错误:HSEARCH000610:未知字段'customFields.town_TextForSort.keyword'。
如果使用 Elasticsearch 界面直接使用路径“customFields.town_TextForSort.keyword”运行搜索,那么它会起作用。 Elasticsearch 返回排序后的结果。
这是 Hibernate Search 6 中的错误吗?因为字段验证失败(Hibernate Search 不知道子字段“关键字”。 还是我的设置有误?如果使用 ObjectStructure.FLATTENED,我假设这些字段都是关键字类型而不是文本。 或者 Elasticsearch 正在创建关键字子字段?如何强制字段为关键字类型而不是文本类型?
首先,Hibernate Search 还不支持多字段(参见 HSEARCH-3465),所以这个
.keyword
子字段不是它可以使用的。
其次,即使有,您在 Elasticsearch 模式中看到的
.keyword
子字段在 Hibernate 搜索端的字段定义中也从未提及:由于服务器端的一些默认模板,它是由 Elasticsearch 自动添加的。所以 Hibernate Search 不会知道这个子字段。
解决方案是添加同级字段而不是依赖多字段。这就是你显然试图做的......但不知何故 Elasticsearch 模式与你在 Hibernate Search 端配置的不匹配:
所以有问题。
我想你要么:
中创建
customFields
对象字段(例如DocumentElement customFields = target.addObject("customFields")
fieldValueTemplate_TextDefault
/fieldValueTemplate_TextForSort
的值添加到根(传递给您的字段的 target
参数),而不是将它们添加到您的 customFields
对象字段。我需要你的活页夹/桥的完整代码和你的完整 Elasticsearch 模式来确定。