How to update nested field using POJO in spring-data-elasticsearch

Viewed 773

I am using spring-data-elasticsearch to use elasticsearch as my datasource. I modeled my entity in this way

Foo.java

@Document(indexName = "foo", shards = 1, versionType = VersionType.INTERNAL, createIndex = true)
public class Foo {

    @Field(type = FieldType.Text, name = "name")
    private String name;

    @Field(type = FieldType.Nested, name = "bar")
    private Bar bars;
}

Bar.java

public class Bar {

    @Field(type = FieldType.Text, name = "name")
    private String name;
}

I am updating only "bar" value in foo document using UpdateQuery as follows

    Map<String, Object> params = new HashMap<>();
            params.put("bar", bar);
UpdateQuery updateQuery = UpdateQuery.builder(id)
                    .withScript("ctx._source.bar = params.bar")
                    .withParams(params)
                    .build();
            UpdateResponse updateResponse = operations.update(updateQuery, index);

I am getting the following error

ava.lang.IllegalArgumentException: cannot write xcontent for unknown value of type class com.myapp.model.Bar
        at org.elasticsearch.common.xcontent.XContentBuilder.unknownValue(XContentBuilder.java:833) ~[elasticsearch-x-content-7.9.3.jar:7.9.3]
        at org.elasticsearch.common.xcontent.XContentBuilder.map(XContentBuilder.java:895) ~[elasticsearch-x-content-7.9.3.jar:7.9.3]
        at org.elasticsearch.common.xcontent.XContentBuilder.map(XContentBuilder.java:870) ~[elasticsearch-x-content-7.9.3.jar:7.9.3]
        at org.elasticsearch.common.xcontent.XContentBuilder.field(XContentBuilder.java:866) ~[elasticsearch-x-content-7.9.3.jar:7.9.3]
        at org.elasticsearch.script.Script.toXContent(Script.java:660) ~[elasticsearch-7.9.3.jar:7.9.3]
        at org.elasticsearch.common.xcontent.XContentBuilder.value(XContentBuilder.java:857) ~[elasticsearch-x-content-7.9.3.jar:7.9.3]
        at org.elasticsearch.common.xcontent.XContentBuilder.value(XContentBuilder.java:850) ~[elasticsearch-x-content-7.9.3.jar:7.9.3]
        at org.elasticsearch.common.xcontent.XContentBuilder.field(XContentBuilder.java:842) ~[elasticsearch-x-content-7.9.3.jar:7.9.3]

Note: I tried updating a foo.name field using script. It worked fine. the problem is using Bar object in update query.

Any idea to solve this problem

1 Answers

The error clearly states that Elasticsearch doesn't know how to store and process class com.myapp.model.Bar because it's specific for your domain (in contrast with String, Boolean etc., which are common for all domains).

So you must explicitly tell to Spring and Elasticsearch how to map com.myapp.model.Bar to simple types and vice versa: create reading and writing converters and then register them in ElasticsearchCustomConversions. See section 6.1.3. Custom Conversions in official documentation for complete example.

Related