简体   繁体   English

Spring 数据 elasticsearch 嵌入字段映射

[英]Spring data elasticsearch embedded field mapping

I'm struggling with mappings some field.我正在为某些领域的映射而苦苦挣扎。 I looked for an answer but couldn't find anything solving my case.我寻找答案,但找不到任何解决我的案子的方法。 Let's cut to the chase.让我们切入正题。

I have my document class我有我的文件 class

@Doucment
public class DocumentClass {
  @Field(type = FieldType.Nested)
  private EmployeeId employeeId;
}

An EmployeeId is wrapper for my uuid identifier. EmployeeId 是我的 uuid 标识符的包装器。 This object has nothing but just getters and setters and jackson annotations.这个 object 只有 getter 和 setter 以及 jackson 注释。 The thing is that object extends some base class so such objects like EmployeeId can inherit this object. This super class has field id and this causes the problem.问题是 object 扩展了一些基数 class,因此像 EmployeeId 这样的对象可以继承这个 object。这个超级 class 有字段 id,这导致了问题。 When I post some data to elasticsearch then it looks like this:当我将一些数据发布到 elasticsearch 时,它看起来像这样:

{
  "employeeId": {
    "id": "someUUID"
  }
}

But I want to map this to be like:但我希望 map 像这样:

{
  "employeeId": "someUUID"
}

I wonder if there is a way to flatten this object.我想知道有没有办法把这个object压扁。

I am guessing you have an Id field which is a string.我猜你有一个 Id 字段,它是一个字符串。

You need to put a @JsonValue annotation on that field to make jackson serialize it the way you want.您需要在该字段上放置一个 @JsonValue 注释,以使 jackson 以您想要的方式序列化它。

Field annotated by JsonValue will be used to serialize your pojo into json.由 JsonValue 注释的字段将用于将您的 pojo 序列化为 json。

If your Id field is private, then add the annotation on the getter of that field.如果您的 Id 字段是私有的,则在该字段的 getter 上添加注释。

https://fasterxml.github.io/jackson-annotations/javadoc/2.8/com/fasterxml/jackson/annotation/JsonValue.html https://fasterxml.github.io/jackson-annotations/javadoc/2.8/com/fasterxml/jackson/annotation/JsonValue.html

If I get it right, you want to convert your EmployeeId class to a String and back.如果我做对了,您想将EmployeeId class 转换为 String 并返回。 You have 2 possibilities to do that:您有两种可能性:

Using a property converter使用属性转换器

If you only want to convert an EmployeeId in this entity and might keep it as it is in another, you should use a property converter that is only registered for this property:如果您只想转换此实体中的EmployeeId并可能将其保留在另一个实体中,则应使用仅为此属性注册的属性转换器:

import org.springframework.data.elasticsearch.core.mapping.PropertyValueConverter;

public class EmployeeIdConverter implements PropertyValueConverter {
    @Override
    public Object write(Object value) {
        return value instanceof EmployeeId employeeId ? employeeId.getId() : value.toString();
    }

    @Override
    public Object read(Object value) {
        return new EmployeeId(value.toString());
    }
}

This converter must be registered on the property, notice that the field type is set to Keyword as it probably should not be analysed:此转换器必须在属性上注册,请注意字段类型设置为Keyword ,因为它可能不应该被分析:

import org.springframework.data.elasticsearch.annotations.ValueConverter;

@Document
public class DocumentClass {
  @Field(type = FieldType.Keyword)
  @ValueConverter(EmployeeIdConverter.class)
  private EmployeeId employeeId;
}

Using a global converter使用全局转换器

If you are using this EmployeeId at several places you might want register globally 2 converters for the two conversion directions:如果您在多个地方使用此EmployeeId ,您可能需要为两个转换方向全局注册 2 个转换器:

@WritingConverter
public class EmployeeIdToString implements Converter<EmployeeId, String>{

    @Nullable
    @Override
    public String convert(EmployeeId employeeId) {
        return employeeId.getId();
    }
}

@ReadingConverter
public class StringToEmployeeId implements Converter<String, EmployeeId>{

    @Nullable
    @Override
    public EmployeeId convert(String id) {
        return new EmployeeId(id);
    }
}

To register these, you need to provide a custom client configuration (see the documentation ):要注册这些,您需要提供自定义客户端配置(请参阅文档):

@Configuration
public class MyClientConfig extends ElasticsearchConfiguration {

    @Override
    public ClientConfiguration clientConfiguration() {
        return ClientConfiguration.builder()           
            .connectedTo("localhost:9200")
            .build();
    }

    @Override
    public ElasticsearchCustomConversions elasticsearchCustomConversions() {
        Collection<Converter<?, ?>> converters = new ArrayList<>();
        converters.add(new EmployeeIdToString());
        converters.add(new StringToEmployeeId());
        return new ElasticsearchCustomConversions(converters);
    }

}

In this case, only the field type needs to be adjusted这种情况下只需要调整字段类型

@Document
public class DocumentClass {
  @Field(type = FieldType.Keyword)
  private EmployeeId employeeId;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM