如何通过ElasticSearch Update API(Painless)拼接对象而非全量替换
Solution to Append Fields to Existing Elasticsearch Document Without Full Overwrite
Your current script replaces the entire ctx._source object when the target document exists, which is why you're losing all original fields from Document A. To dynamically append all fields from Document B without hardcoding each one (perfect for scenarios with lots of fields), you can use a Painless script that iterates over the key-value pairs in your parameter and adds them to the existing source.
Step-by-Step Fix
- Replace your script logic with a loop that iterates over every entry in your
param1parameter. This will add each field from Document B to Document A's source without overwriting existing fields (if a field with the same name exists in both, it will be updated to the value from Document B—you can adjust this if needed, see note below). - Keep the rest of your update request intact (the
upsertclause is still useful for handling cases where the document doesn't exist yet).
Updated Request Body
{"update":{"_index":"test-index","_id":"121423"}} {"script": { "source": "for (entry in params.param1.entrySet()) { ctx._source[entry.getKey()] = entry.getValue(); }", "lang":"painless", "params":{"param1":{"city": "New York", "job": "programmer"}} }, "upsert":{"id":121423,"name": "Sample Name","timestamp": "2020-10-01T00:12:00","age":24}}
Key Details
- The
entrySet()method lets us iterate over all key-value pairs inparam1. For each pair, we add the key toctx._sourceand set its value to the corresponding value from Document B. - If you want to avoid overwriting existing fields (only add fields that don't already exist in Document A), modify the script to include a check:
for (entry in params.param1.entrySet()) { if (!ctx._source.containsKey(entry.getKey())) { ctx._source[entry.getKey()] = entry.getValue(); } } - This approach is scalable—no matter how many fields are in Document B, you won't need to update the script.
Result After Update
Once you run this request, Document A will be updated to exactly what you're expecting:
{"id": 121423, "name": "Sample Name", "timestamp": "2020-10-01T00:12:00", "age": 24, "city": "New York", "job": "programmer"}
内容的提问来源于stack exchange,提问作者Augusto
相关产品推荐
相关产品推荐

