elasticsearch/elasticsearch — pull request #5291 by seut (2014-02-28 10:48:11+00:00)
Title: Implemented update by paths in order to overwrite document fields instead of merge

We've implemented a new feature for overwriting doc fields instead of merging values in.
This is done by defining the paths to sub-fields instead of submitting an updated doc.
It gives us the opportunity to overwrite a complete object by a new one, and so deleting unwanted keys.
This is maybe most useful when using dynamic mapping on object fields.

## Demonstration Example (Documentation):

### Create an index
```shell
curl -XPUT 'http://localhost:9200/twitter'
```
### Create a document mapping with a field of type `object`
```shell
curl -XPUT 'http://localhost:9200/twitter/tweet/_mapping' -d '{
"tweet" : {
"properties" : {
"person" : {
"type" : "object",
"properties" : {
"name" : {"type" : "object"},
"sid" : {"type" : "string", "index" : "not_analyzed"}
}
},
"message" : {"type" : "string"}
}
}
}'
```

### Index a document
```shell
curl -XPUT 'http://localhost:9200/twitter/tweet/1' -d '{
"person" : {
"name" : {
"first_name" : "Shay",
"last_name" : "Banon",
"nick_name": "kimchy"
},
"sid" : "12345"
},
"message" : "This is a tweet!"
}'
```
### Update the document in order to delete the `person.name.nick_name` field
#### Can be done by submitting the paths by using the `paths` key
```shell
curl -XPOST 'http://localhost:9200/twitter/tweet/1/_update' -d '{
"paths" : {
"person.name" : {
"first_name" : "Shay",
"last_name" : "Banon"
}
}
}'
```
#### Validate the updated document (`nick_name` removed)
```shell
curl -XGET 'http://localhost:9200/twitter/tweet/1'
{
"_index" : "twitter",
"_type" : "tweet",
"_id" : "1",
"_version" : 2,
"exists" : true,
"_source" : {
"person" : {
"name" : {
"first_name" : "Shay",
"last_name" : "Banon"
},
"sid" : "12345"
},
"message" : "This is a tweet!"
}
}
```
#### Same can be achieved by using `doc` in conjunction with `doc_as_paths=true`
```shell
curl -XPOST 'http://localhost:9200/twitter/tweet/1/_update' -d '{
"doc" : {
"person.name" : {
"first_name" : "Shay"
}
},
"doc_as_paths" : true
}'
```
#### Validate the updated document (now `last_name` is removed)
```shell
curl -XGET 'http://localhost:9200/twitter/tweet/1'
{
"_index" : "twitter",
"_type" : "tweet",
"_id" : "1",
"_version" : 3,
"exists" : true,
"_source" : {
"person" : {
"name" : {
"first_name" : "Shay"
},
"sid" : "12345"
},
"message" : "This is a tweet!"
}
}
```

Of course `paths` can also be used to update non-objects.