elasticsearch,jsonb,hibernate-search,Java,Spring Boot,elasticsearch,Jsonb,Hibernate Search" /> elasticsearch,jsonb,hibernate-search,Java,Spring Boot,elasticsearch,Jsonb,Hibernate Search" />

Java Hibernate搜索JsonB索引

Java Hibernate搜索JsonB索引,java,spring-boot,elasticsearch,jsonb,hibernate-search,Java,Spring Boot,elasticsearch,Jsonb,Hibernate Search,我正在努力使用HibernateSearch 6.0.2将jsonB列索引到Elasicsearch后端 这是我的实体: @Data @NoArgsConstructor @Entity @Table(name = "examples") public class Example { @Id @GeneratedValue(strategy = GenerationType.AUTO) private UUID id; @NotNull

我正在努力使用HibernateSearch 6.0.2将jsonB列索引到Elasicsearch后端

这是我的实体:

@Data
@NoArgsConstructor
@Entity
@Table(name = "examples")
public class Example {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private UUID id;

    @NotNull
    @Column(name = "fields")
    @Type(type = "jsonb")
    private Map<String, Object> fields;
}
我的自定义属性绑定器实现基于HibernateSearch6.0.2

但它抛出了一个例外:

org.hibernate.search.util.common.SearchException: HSEARCH400609: Unknown field 'metadata.testNumber'.
我还在spring应用程序中将dynamic_mapping设置为true:

...
spring.jpa.properties.hibernate.search.backend.hosts=127.0.0.3:9200
spring.jpa.properties.hibernate.search.backend.dynamic_mapping=true
...
还有其他想法吗?我如何解决这个问题?或者我在什么地方出错了

我知道文档为映射中的对象定义了多个模板(如MultiTypeUserMetadataBinder示例),但我真的不知道其中可以包含什么。据我所知,它是一个有效的json,我的目标是将其作为“字段”下的有效json结构放入Elasticsearch中:{…}

如果您不知道每个字段的类型,Hibernate搜索将帮不上什么忙。如果你真的想把它塞进你的索引中,我建议声明一个,并按原样推送JSON。但是,您将无法轻松地将谓词应用于元数据字段,除非使用

大概是这样的:

    {
        "testString": "298",
        "testNumber": 123,
        "testBoolean": true,
        "testNull": null,
        "testArray": [
            5,
            4,
            3
        ],
        "testObject": {
            "testString": "298",
            "testNumber": 123,
            "testBoolean": true,
            "testNull": null,
            "testArray": [
                5,
                4,
                3
            ]
        }
@组件
公共类JsonPropertyBinder实现PropertyBinder{
@凌驾
公共void绑定(PropertyBindingContext){
context.dependentials().useRootOnly();
var schemaElement=context.indexSchemaElement();
//改变这个
IndexFieldReference userMetadataField=schemaElement.field(
“元数据”,
f->f.extension(ElasticsearchExtension.get())
.asNative().mapping(“{\”类型\“:\”对象\“,\”动态\“:真}”);
)
.toReference();
桥(Map.class,新桥(userMetadataField));
}
@所需参数构造函数
私有静态类桥实现PropertyBridge{
私有静态最终Gson Gson=new Gson();
私有最终索引字段引用字段引用;
@凌驾
公共无效写入(DocumentElement目标、映射bridgedElement、PropertyBridgeWriteContext){
//改变这个
target.addValue(fieldReference,GSON.toJsonTree(bridgedElement));
}
}
}
或者,您可以将所有字段声明为字符串。然后,Hibernate搜索字符串类型提供的所有功能都将可用。但当然,范围谓词或排序之类的东西会导致对数值产生奇怪的结果(
2
10
之前,而
“2”
“10”
之后)

大概是这样的:

    {
        "testString": "298",
        "testNumber": 123,
        "testBoolean": true,
        "testNull": null,
        "testArray": [
            5,
            4,
            3
        ],
        "testObject": {
            "testString": "298",
            "testNumber": 123,
            "testBoolean": true,
            "testNull": null,
            "testArray": [
                5,
                4,
                3
            ]
        }
@组件
公共类JsonPropertyBinder实现PropertyBinder{
@凌驾
公共void绑定(PropertyBindingContext){
context.dependentials().useRootOnly();
var schemaElement=context.indexSchemaElement();
var userMetadataField=schemaElement.objectField(“元数据”);
//加上这个
userMetadataField.fieldTemplate(
“userMetadataValueTemplate\u默认值”,
f->f.asString().analyzer(“英语”)
);
桥(Map.class,新桥(userMetadataField.toReference());
}
@所需参数构造函数
私有静态类桥实现PropertyBridge{
私有最终IndexObjectFieldReference字段引用;
@凌驾
公共无效写入(DocumentElement目标、映射bridgedElement、PropertyBridgeWriteContext){
var map=target.addObject(fieldReference);
//改变这个
((Map)bridgedElement.forEach(entry->Map.addValue(entry.getKey(),String.valueOf(entry.getValue()));
}
}
}

完美!我使用Hibernate搜索作为数据同步工具。如果要执行任何搜索,则将在不同的服务范围内执行,或直接通过elasticsearch API执行。
...
spring.jpa.properties.hibernate.search.backend.hosts=127.0.0.3:9200
spring.jpa.properties.hibernate.search.backend.dynamic_mapping=true
...