1

Is there any way to make a super-class document (e.g. index name = user) and create two child classes (Admin, Guest) to save all this to user index but with different fields? E.g. Add to super-class field type and based on this field fetch right entity? ELK 7.19, Spring Data 4.3.1.

2

1 Answer 1

2

You can do that. Make the base class abstract. I have this in a test setup with the following classes:

@Document(indexName = "type-hints")
public abstract class BaseClass {

    @Id
    private String id;

    @Field(type = FieldType.Text)
    private String baseText;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getBaseText() {
        return baseText;
    }

    public void setBaseText(String baseText) {
        this.baseText = baseText;
    }

    @Override
    public String toString() {
        return "BaseClass{" +
            "id='" + id + '\'' +
            ", baseText='" + baseText + '\'' +
            '}';
    }
}
public class DerivedOne extends BaseClass {
    @Field(type = FieldType.Text)
    private String derivedOne;

    public String getDerivedOne() {
        return derivedOne;
    }

    public void setDerivedOne(String derivedOne) {
        this.derivedOne = derivedOne;
    }

    @Override
    public String toString() {
        return "DerivedOne{" +
            "derivedOne='" + derivedOne + '\'' +
            "} " + super.toString();
    }
}
public class DerivedTwo extends BaseClass {
    @Field(type = FieldType.Text)
    private String derivedTwo;

    public String getDerivedTwo() {
        return derivedTwo;
    }

    public void setDerivedTwo(String derivedTwo) {
        this.derivedTwo = derivedTwo;
    }

    @Override
    public String toString() {
        return "DerivedTwo{" +
                "derivedTwo='" + derivedTwo + '\'' +
                "} " + super.toString();
    }
}
interface TypeHintRepository extends ElasticsearchRepository<BaseClass, String> {
    SearchHits<? extends BaseClass> searchAllBy();
}
@RestController
@RequestMapping("/typehints")
public class TypeHintController {

    private static final Logger LOGGER = LoggerFactory.getLogger(TypeHintController.class);

    private final TypeHintRepository repository;

    public TypeHintController(TypeHintRepository repository) {
        this.repository = repository;
    }

    @GetMapping
    public void test() {

        List<BaseClass> docs = new ArrayList<>();

        DerivedOne docOne = new DerivedOne();
        docOne.setId("one");
        docOne.setBaseText("baseOne");
        docOne.setDerivedOne("derivedOne");
        docs.add(docOne);

        DerivedTwo docTwo = new DerivedTwo();
        docTwo.setId("two");
        docTwo.setBaseText("baseTwo");
        docTwo.setDerivedTwo("derivedTwo");
        docs.add(docTwo);

        repository.saveAll(docs);

        SearchHits<? extends BaseClass> searchHits = repository.searchAllBy();

        for (SearchHit<? extends BaseClass> searchHit : searchHits) {
            LOGGER.info(searchHit.toString());
        }
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Great! You save my day!
Now what if I want to use a different index for the derived document? Will it work if I simply add a @Document(indexName = "index-derived") annotation?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.