Elasticsearch 6.1原子更新:保留指定顶层字段删除其余字段
Atomic Update to Keep Only Specific Top-Level Fields in Elasticsearch 6.1
Great question! Instead of manually removing every unwanted field one by one (which gets tedious if you have lots of fields), you can replace the entire ctx._source object with a new map that only includes your desired fields (a and b). This is a clean, atomic approach that leverages Elasticsearch's Painless scripting.
Here's the complete curl command to achieve this:
curl -XPOST 'localhost:9200/index/type/id/_update' -H 'Content-Type: application/json' -d '{ "script": { "source": """ // Create an empty map to hold only the fields we want to keep def newSource = [:]; // Iterate over the list of fields to retain params.fields.each { field -> // Only copy the field if it exists in the original source if (ctx._source.containsKey(field)) { newSource[field] = ctx._source[field]; } } // Replace the original source with our filtered version ctx._source = newSource; """, "params": { "fields": ["a", "b"] } } }'
How This Works:
- We initialize an empty Painless map (
newSource) to store our desired fields. - We loop through the
fieldsparameter (which listsaandbhere) and check if each field exists in the original document's_source. - If the field exists, we copy its value into
newSource. - Finally, we overwrite
ctx._sourcewithnewSource—this effectively deletes all other fields from the document, leaving onlyaandb(if they existed in the original document).
Key Notes:
- This operation is atomic: Elasticsearch locks the document during the update, so no concurrent modifications can interfere.
- If either
aorbdoesn't exist in the original document, it simply won't appear in the updated document (no errors thrown). - The
Content-Type: application/jsonheader is required in Elasticsearch 6.x to properly parse the request body.
内容的提问来源于stack exchange,提问作者Didac Montero




