0
votes

I saw Spring Boot's mapping with the document annotation. Using the @Document annotation to define the index obligates me to specific amount of fields and specific fields names. In my application users define their own fields, so @Document is not a good match for my needs.

How can I achieve dynamic fields for a specific index with spring data?

example:

A user generates some data:

Map<String, String> data = new HashMap<>();
//new fields
data.put("oranges", "tasty");
data.put("apples", "baaa");
data.put("avocado", "ok");
// existing fields
data.put("totalFruits", 20);

and calls a method, lets say:

void indexData(String indexName, Map<String, String> data)

Output will be:

  • the addition of the 3 fields to the index
  • a new document in index indexName containing all fields
1

1 Answers

0
votes

Be aware that the linked document is a couple of years old.

With Spring Data Elasticsearch it is possible to index objects of different classes (not just Maps) to the same index, not with the Repository methods but with the methods of the implementations of the ElasticsearchOperations interface.

You can achieve this by using the ElasticsearchOperations.index(IndexQuery query) for versions up to the current version 3.2. From 4.0 on this will become DocumentOperations.index(IndexQuery, IndexCoordinates).
The IndexQuery contains a field that specifies the index name where the document data should be stored to. From version 4.0 on, the information in the second parameter is used to pass this information.

If you store data this way, be aware that the index mappings are not created by Spring Data Elasticsearch and you have no control over it. If first a document containing

data.put("count", 20)

is stored, and later another document is stored with

data.put("count", "twenty")

you will get an error, because the count field was automatically mapped to a numerical value and not to a String.
Or if you store objects of two different classes that both have a property with the same name but different typ, you will get the same error.

So technically it is possible, but I would really not recommend to store data in this way.