I have a test domain class
public class TestDocument {
private final String id;
private final String strField;
private final Integer intField;
public TestDocument(final String id, final String strField, final Integer intField) {
this.id = id;
this.strField = strField;
this.intField = intField;
}
}
now I invoke ElasticsearchRestTemplate.save
method with 3 documents and want to save into 3 different indices.
@Service
public class TestEsService {
@Autowired
private ElasticsearchRestTemplate elasticsearchRestTemplate;
@PostConstruct
public void testSave() {
final TestDocument d1 = new TestDocument("id_1", "str1", 1);
final TestDocument d2 = new TestDocument("id_2", "str2", 2);
final TestDocument d3 = new TestDocument("id_3", "str3", 3);
this.save(List.of(d1, d2, d3));
}
public void save(final List<TestDocument> documents) {
final IndexCoordinates indexCoordinates = IndexCoordinates.of("index_1", "index_2", "index_3");
this.elasticsearchRestTemplate.save(documents, indexCoordinates);
}
}
After executed above code. I check my local elasticsearch.
curl -H 'Content-Type: application/json' 'http://localhost:9200/_cat/indices?pretty' -s
I got only one index in my ES.
yellow open index_1 17ppJ9vJRUGIVHYBKKxXog 1 1 3 0 5.5kb 5.5kb
and check the data of this index_1
index:
curl 'http://localhost:9200/index_1/_search?pretty'
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 3,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "index_1",
"_type" : "_doc",
"_id" : "id_1",
"_score" : 1.0,
"_source" : {
"_class" : "com.test.entity.TestDocument",
"id" : "id_1",
"strField" : "str1",
"intField" : 1
}
},
{
"_index" : "index_1",
"_type" : "_doc",
"_id" : "id_2",
"_score" : 1.0,
"_source" : {
"_class" : "com.test.entity.TestDocument",
"id" : "id_2",
"strField" : "str2",
"intField" : 2
}
},
{
"_index" : "index_1",
"_type" : "_doc",
"_id" : "id_3",
"_score" : 1.0,
"_source" : {
"_class" : "com.test.entity.TestDocument",
"id" : "id_3",
"strField" : "str3",
"intField" : 3
}
}
]
}
}
after dive into the code:
I found a clue within RequestFactory.bulkRequest
:
queries.forEach(query -> {
if (query instanceof IndexQuery) {
bulkRequest.add(indexRequest((IndexQuery) query, index));
} else if (query instanceof UpdateQuery) {
bulkRequest.add(updateRequest((UpdateQuery) query, index));
}
});
actually IndexRequest()
gets index name via index.getIndexName();
method:
public IndexRequest indexRequest(IndexQuery query, IndexCoordinates index) {
String indexName = index.getIndexName();
IndexRequest indexRequest;
where IndexCoordinates.getIndexName()
return the first index name only.
public String getIndexName() {
return indexNames[0];
}
Is it a bug? Should I report to spring-data-elasticsearch Github issue?
Multiple names in IndexCoordinates
are used when accessing an Elasticsearch API that uses multiple index names, for example when searching data in multiple indices, but not for writing access.
If you want to save the 3 entities to 3 indices, you need 3 calls with different IndexCoordinates
- each of these having one index name.