Document Model
Data Types
REGISTER
t he register type is the core building block of every app built on ditto this article provides an overview of the register type, including its merge strategy and the various scalar subtypes you can use to encode single values within a register supported scalar subtypes a register stores a single scalar value you can encode the value using any json ‑ compatible scalar subtype, such as a string , boolean , json object to represent two or more fields as a single object , and so on the following table provides an overview of the different scalar types you can use to store a single value in a register data type corresponding values array an ordered list of values, where each value represents any primitive type, as well as nested collection types such as other arrays or map type boolean true or false float 64 bit floating point int signed 64 bit integer json object embedded json blob null represents an absence of a value string utf 8 encodable unsigned int unsigned 64 bit integer example updating a register for example, the following snippet shows a basic update statement query setting the values of two separate registers a register storing a string set to the value 'blue' a register storing an integer set to the value 3001 dql update cars set name = 'blue' mileage = 3001 where id = '123' limitations to arrays unlike typical arrays , the multiple elements within an array scalar subtype function collectively as a single register with last write wins merge behavior an array scalar subtype is an ordered collection of items represented using any primitive json‑compatible data type enclosed within square brackets (\[ ]) the array scalar subtype, while great at managing unordered operations, such as a gps coordinate where both latitude and longitude values change together, as follows, maintaining a strict order could potentially lead to data inconsistencies at merge "location" { "coordinates" \[ 122 0308, 37 3318], "address" "123 main st, san francisco, ca 94105" } considering this, when managing collections of data that have concurrent editors, opt for a map instead, which effectively functions as a set, more commonly known as an associative array for more information, see docid\ d2pyb8qyu ww vyjjuiqj last write wins merge strategy the register type adheres to the last write wins principle when handling concurrency conflicts this means that when changes occur, all peers observing the change will sequence these changes in the same order this ensures that only a consistent single value syncs across the entire peer to peer mesh for example, one flight attendant updates a customer's seat number to 6 and another to seat 9 when the two conflicting versions merge, the edit with the highest timestamp wins put another way, by enforcing the last write wins merge strategy, for events a and b, where b is a result of a, event a always occurs before b syncing with register each register in a document syncs independently when the value that the register holds changes, the entire register value syncs across the mesh for example, the following code, once executed, results in the field color being changed and the value 'blue' being synced across peers dql update cars set color = 'black' where id = '123abc' since a register acts as a single object, to update just the color , you'd need to update the entire object by providing the entire set of nested key value pairs, including the modified color , as follows let newproperties = \[ "color" "blue", "sunroof" true, "door count" 4 ] await ditto store execute( "update cars set properties = \ newproperties where id = '123'", \["newproperties" newproperties]);var result = ditto store execute( "insert into cars documents (\ newcar)", mapof("newproperties" to mapof("color" to "blue", "sunroof" to true, "door count" to 4)))const newproperties = { color 'blue', sunroof true, door count 4 } await ditto store execute( "update cars set properties = \ newproperties where id = '123'", {newproperties});map\<string, string> newproperties = new hashmap<>(); newcar put("color", "blue"); newcar put("sunroof", true); newcar put("door count", 4); dittoqueryresult result = (dittoqueryresult) ditto store execute( "update cars set properties = \ newproperties where id = '123'", collections singletonmap("newproperties", newproperties), new continuation<>() { @nonnull @override public coroutinecontext getcontext() { return emptycoroutinecontext instance; } @override public void resumewith(@nonnull object o) { if (o instanceof result failure) { // handle failure } } } ); var args = new dictionary\<string, object>(); args add("newproperties", new { color="blue", sunroof=true, doorcount=4}); await ditto store executeasync( "update cars set properties = \ newproperties where id = '123'", args);struct properties { std string color; bool sunroof; int door count; }; // std map\<std string, properties> args; args\["newproperties"] = {"blue", true, 4}; ditto get store() execute( "update cars set properties = \ newproperties where id = '123'", args);struct properties { color string, sunroof bool, door count i32 } struct args { newproperties properties, } // let args = args { newproperties properties { color "blue" to string(), sunroof true, door count 4 } }; await ditto store() execute( "update cars set properties = \ newproperties where id = '123'", args);