Document JSON format - Update

Vespa supports making changes to an existing document without submitting the entire document. This is called partial update. A partial update consists of the id of the existing document to update, and the operation or operations to perform on selected fields of the document.

Documents can be auto-created on updates using create if nonexistent. Also see conditional updates. All data structures (attribute, index and summary) are updatable. The following operations are supported:

All field types
  • assign (may also be used to clear fields)
Numeric field types
Composite types

assign

assign is used to completely replace the value of a field with a new value. The new value is specified as an "action" for the field in the set of fields. Example:

{
    "update": "id:music:music::docid123",
    "fields": {
        "title": {
            "assign": "The best of Bob Dylan"
        }
    }
}
If the field is to be cleared, assign null to it. Example assign update to a tensor field with tensor type tensor(x{},y{}):
{
    "update": "id:tensordoctype:tensordoctype::example2",
    "fields": {
        "tensorfield": {
            "assign": {
                "cells": [
                    { "address": { "x": "a", "y": "b" }, "value": 2.0 },
                    { "address": { "x": "c", "y": "d" }, "value": 3.0 }
                ]
            }
        }
    }
}
assign can use fieldpath syntax when used on compiste types when they are not part of attribute or index. On a map it can be used as a put. In the following example a tuple (key1, value1) is inserted into the map regardless if there is an element with key "key1" before:
{
    "update": "id:music:music::example2",
    "fields": {
        "mapfield{key1}": {
            "assign": "value1"
        }
    }
}
assign can be used on structs to set one field Note: does not work for index mode:
{
    "update": "id:music:music::example3",
    "fields": {
        "structfieldperson.firstname": { "assign": "bob" },
        "structfieldperson.lastname": { "assign": "the plumber" }
    }
}
assign can be used on array to set one element. In this example we have an array of strings:
{
    "update": "id:music:music::example4",
    "fields": {
        "arrayfield[34]": { "assign": "bob" },
    }
}

add

add is used to add entries to multi-value fields: Arrays, tags, and weighted sets. Map does not support add - to put an element into a map type, see assign above. If the value is already present in the weighted set, the weight from the update will replace the old weight. Example:

{
    "update": "id:music:music::http://music.yahoo.com/bobdylan/BestOf",
    "fields": {
       "tracks": {
            "add": [
                "Lay Lady Lay",
                "Every Grain of Sand"
            ]
        }
    }
}
In other words, for the array field "tracks", we add the values from the add array. Example of adding an element to a weighted set:
{
    "update":"id:weightedsetdoctype:weightedsetdoctype::example1",
    "fields":  {
        "weightedsetfield": {
            "add": {
                "britney":12
            }
        }
    }
}
Note that if the element already exist the value will be overwritten. Example of an assign to a weighted set:
{
    "update":"id:weightedsetdoctype:weightedsetdoctype::example1",
    "fields": {
        "intweightedsetfield":  {
            "assign": {
                "123": 123,
                "456": 100
            }
        },
        "stringweightedsetfield": {
            "assign": {
                "item 1": 144,
                "item 2": 7
            }
        }
    }
}

remove

Example of removing an element from a weighted set:

{
    "update":"id:weightedsetdoctype:weightedsetdoctype::example1",
    "fields":  {
        "weightedsetfield": {
            "remove": {
                "britney": 0
            }
        }
    }
}

increment, decrement, multiply, divide

The four arithmetic operators increment, decrement, multiply and divide are used to modify single value numeric values without having to look up the current value before applying the update. Example:

{
    "update": "id:music:music::http://music.yahoo.com/bobdylan/BestOf",
    "fields": {
        "sales": {
            "increment": 1
        }
    }
}

match

If an action, like an arithmetic operation, is to be done for a specific key in a composite structure, use the match operation:

{
    "update": "id:music:music::http://music.yahoo.com/bobdylan/BestOf",
    "fields": {
        "trackPopularity": {
            "match": {
                "element": "Lay Lady Lay",
                "increment": 1
            }
        }
    }
}
In other words, for the weighted set "trackPopularity", match the element "Lay Lady Lay", then increment its weight by 1.

Note: Only one element in a weighted set can be matched per update.

create (create if nonexistent)

Updates to nonexistent documents are supported using the create field - an empty document is created on the content node before the update is applied. This simplifies client code in the case of multiple writers:

{
    "update": "id:music:music::http://music.yahoo.com/bobdylan/BestOf",
    "create": true,
    "fields": {
        "title": {
            "assign": "The best of Bob Dylan"
        }
    }
}
Java example:
public DocumentUpdate createUpdate(DocumentType musicType) {
  DocumentUpdate update = new DocumentUpdate(musicType, "id:music:music::0");
  update.setCreateIfNonExistent(true);
}
Note: create cannot be used in combination with condition. This is due to the Vespa consistency model and use of timestamps on the document level for eventual consistency.

fieldpath

Fieldpath is for accessing fields within composite structures - for structures that are not part of index or attribute, it is possible to access elements directly using fieldpaths. This is done by adding more information to the field value. For map structures, specify the key (see example).

mymap{mykey}
and then do operation on the element which is keyed by "mykey". Arrays can be accessed as well (see details).
myarray[3]
And this is also true for structs (see details). Note: Struct updates does not work for index mode:
mystruct.value1
This also works for nested structures, e.g. a map of map to array of struct:
{
    "update": "id:music:music::http://music.yahoo.com/bobdylan/BestOf",
    "fields": {
        "nestedstructure{firstMapKey}{secondMapKey}[4].title": {
            "assign": "The best of Bob Dylan"
        }
    }
}