Reputation: 3256
Let's say I have a tag
type in an ElasticSearch index, with the following mapping:
{
"tag": {
"properties": {
"tag": {"type": "string", "store": "yes"},
"aliases": {"type": "string"}
}
}
}
Each entry is a tag, and an array of aliases to that tag. Here is an example item:
{
"word": "weak",
"aliases": ["anemic", "anaemic", "faint", "flimsy"]
}
From time to time, I want to add new tag words with their aliases, and add new aliases to existing tag words.
Adding new tag words with their aliases is easy, it's just a new Document. However, how can I add new aliases to existing tag words in a sane way?
I know I can just search for the tag word, get its document, search to see if the alias already exists in the array of aliases, if not add it, than save. However - this does not sound like a good solution.
Is there a way to do a bulk update?
Upvotes: 15
Views: 59964
Reputation: 1194
You can use the ElasticSeach Bulk API for updating the multiple documents using a single API call
CURL example
curl --location --request POST 'localhost:9200/whatsapp/_bulk' \
--header 'Content-Type: application/json' \
--data-raw '{ "update" : {"_id" : 692, "_index" : "whatsapp","_type":"_doc","retry_on_conflict" : 3} }
{ "doc" : {"thread_status" : 1} }
{ "update" : {"_id" : 693, "_index" : "whatsapp","_type":"_doc","retry_on_conflict" : 3} }
{ "doc" : {"thread_status" : 1} }
'
NOTE The final line of data must end with a newline character \n. That' why you will notice ' at the end line of json.
Upvotes: 1
Reputation: 30163
All updates in ElasticSearch are done by finding the record, deleting the old version and adding the new version. You can save a little bit on moving records all the way to the client by using Update API. It would still require finding the record though.
What you, probably, want is Update by query.
Upvotes: 11
Reputation: 794
This works for me.
input_list.dat:
{ "index" : { "_index": "my_index", "_type": "my_type", "_id": "existing-value" } }
{ "Field_to_update": "New_Value" }
{ "index" : { "_index": "my_index", "_type": "my_type", "_id": "existing_value" } }
{ "Field_to_update": "New_Value" }
Command:
curl -k -XPOST 'https://my_host:9200/my_url/_bulk' --data-binary "@input_list.dat"; echo
Upvotes: 5
Reputation: 584
Elasticsearch 2.3.0 introduced the Update By Query API as part of the long awaited Reindex API.
As an example, here is how you could update all documents to delete a certain field if it exists:
POST /myindex/mytype/_update_by_query
{
"script": {
"inline": "ctx._source.remove(\"remove\")"
},
"query": {
"exists": {
"field": "remove"
}
}
}
The above example uses inline scripting, so be sure to enable it in elasticsearch.yml
with script.inline: on
.
Upvotes: 4
Reputation: 397
You can do the same using spring java client using the following code. Following are the dependencies used in the code.
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.index.query.QueryBuilder;
import org.springframework.data.elasticsearch.core.query.UpdateQuery;
import org.springframework.data.elasticsearch.core.query.UpdateQueryBuilder;
private UpdateQuery updateExistingDocument(String Id) {
// Add updatedDateTime, CreatedDateTime, CreateBy, UpdatedBy field in existing documents in Elastic Search Engine
UpdateRequest updateRequest = new UpdateRequest().doc("UpdatedDateTime", new Date(), "CreatedDateTime", new Date(), "CreatedBy", "admin", "UpdatedBy", "admin");
// Create updateQuery
UpdateQuery updateQuery = new UpdateQueryBuilder().withId(Id).withClass(ElasticSearchDocument.class).build();
updateQuery.setUpdateRequest(updateRequest);
// Execute update
elasticsearchTemplate.update(updateQuery);
}
Upvotes: 0
Reputation: 29
Elastic Search has a Update API. With that API you can do the following:
curl -XPOST 'localhost:9200/test/tag/weak/_update' -d '{
"script" : "ctx._source.aliases += faint"
}'
Upvotes: 2
Reputation: 593
Try this using _bulk:
http://127.0.0.1:9200/myindex/type/_bulk
{
"update": {
"_index": "myindex",
"_type": "type",
"_id": "myid"
}
}{
"doc": {
"field": "new value"
}
}{
"update": {
"_index": "myindex",
"_type": "type",
"_id": "id"
}
}{
"doc": {
"field": "new value"
}
}
Upvotes: 15
Reputation: 1755
Elasticsearch's bulk APIs can be used for update requests as well, at least for the Java client.
List list = new Arraylist();
list.add("hello");
BulkProcessor bulk = new BulkProcessor();
UpdateRequest update = new UpdateRequest("index", "type", "id1");
update.script("ctx._source.aliases+= newaliases"); //dynamic script
update.addScriptParam("newaliases", list);
bulk.add(update);
Note that dynamic scripting is disabled in newer versions of elasticsearch. Either enable that or use pre-compiled scripts for using this feature.
Upvotes: 0
Reputation: 314
Also if you add same value with same id, it will automatically update older data.
Upvotes: 0