Skip to main content
See Document Model for more information on documents in Ditto. There are two ways to modify documents in DQL:
1
UPDATEWhen executing UPDATE to apply changes, only the minimum data necessary to enforce all peers converge on one view of the data sync across the mesh. (Updating)
2
INSERTWhile INSERT operations modify all provided fields, even if they remain unchanged. (Inserting)

Updating

To optimize performance and reduce unnecessary overhead, apply most updates in your app through the UPDATE method instead.
For the full DQL syntax, see Ditto Query Language UPDATE.
Here is an example of a basic UPDATE operation on the cars collection:

try await ditto.store.execute("""
  UPDATE cars
  SET color = 'blue'
  WHERE _id = '123'
  """);
ditto.store.execute("""
  UPDATE cars
  SET color = 'blue'
  WHERE _id = '123'
  """)
await ditto.store.execute(`
  UPDATE cars
  SET color = 'blue'
  WHERE _id = '123'`
);
await ditto.store.execute(`
  UPDATE cars
  SET color = 'blue'
  WHERE _id = '123'`
);
// This try-with-resources block auto-closes the DittoQueryResult
try (DittoQueryResult result = ditto.getStore().execute(
        "UPDATE cars SET color = 'blue' WHERE _id = '123'"
    ).toCompletableFuture().join()) {
    ...
}
await ditto.Store.ExecuteAsync(
  "UPDATE cars SET color = 'blue' WHERE _id = '123'");
ditto.get_store().execute(
  "UPDATE cars SET color = 'blue' WHERE _id = '123'");
ditto.store().execute(
  "UPDATE cars SET color = 'blue' WHERE _id = '123'",
).await?;
await ditto.store.execute("""
  UPDATE cars
  SET color = 'blue'
  WHERE _id = '123'
""");
result, err = dit.Store().Execute(
	"UPDATE cars SET color = 'blue' WHERE _id = '123'")
if err != nil {
    return err
}
defer result.Close()  // cleanup

MAP Data Type

To add a MAP to a document, use the dot syntax, which allows you to edit multiple child fields within a single MAP:
UPDATE COLLECTION cars (properties MAP)
SET
  properties.color = 'red',
  properties.mileage = 3001
WHERE
  _id = '123'

Multiple Documents

Modify multiple documents simultaneously based on a specified condition. For example, here is a snippet demonstrating the UPDATE operation modifying all documents in the cars collection that are currently red, and changing their color to blue. After the update, you can reference the documents modified by the mutatedDocumentIDs method on the result of the update.

let result = try await ditto.store.execute(
  "UPDATE cars SET color = 'blue' WHERE _id = '123'");

result.mutatedDocumentIDs.forEach() { print($0) }
ditto.store.execute("""
    UPDATE cars
    SET color = 'blue'
    WHERE _id = '123'
""") { result ->
    result.mutatedDocumentIds().forEach { id ->
        println(id)
    }
}
const result = await ditto.store.execute(`
  UPDATE cars
  SET color = 'blue'
  WHERE color = 'red'`
);

console.log(result.mutatedDocumentIDs().value);
import { QueryResult } from '@dittolive/ditto';

const result: QueryResult = await ditto.store.execute(`
  UPDATE cars
  SET color = 'blue'
  WHERE color = 'red'`
);

console.log(result.mutatedDocumentIDs());
// This try-with-resources block auto-closes the DittoQueryResult
try (DittoQueryResult result = ditto.getStore().execute((
    "UPDATE cars SET color = 'blue' WHERE color = 'red'").toCompletableFuture().join()) {
    for (DittoCborSerializable id : result.getMutatedDocumentIds()) {
        System.out.println(id.asString());
    }
}
using var result = await ditto.Store.ExecuteAsync(
  "UPDATE cars SET color = 'blue' WHERE color = 'red'");

result.MutatedDocumentIDs.ForEach(id => Console.WriteLine(id));
ditto.get_store().execute(
  "UPDATE cars SET color = 'blue' WHERE color = 'red'");
ditto.store().execute(
  "UPDATE cars SET color = 'blue' WHERE color = 'red'",
).await?;
await ditto.store.execute("""
  UPDATE cars
  SET color = 'blue'
  WHERE color = 'red'
""");
result, err := ditto.Store().Execute(
	"UPDATE cars SET color = :newColor WHERE color = :oldColor",
	ditto.QueryArguments{
		"newColor": "blue",
		"oldColor": "red",
	},
)
if err != nil {
    return err
}
defer result.Close()  // cleanup

for _, id := range result.MutatedDocumentIDs() {
	log.Printf("%s", id)
}

Inserting with UPDATE

The INSERT operation provides conflict policy options to override default behavior if a document with the same ID already exists.
For the full DQL syntax, see Ditto Query Language INSERT.
By using the ON ID CONFLICT DO UPDATE policy, inserted documents automatically apply updates for all provided fields.
To optimize performance and reduce unnecessary overhead, apply most data modifications in your app through the UPDATE method.

var document = [
  "_id": "123",
  "color": "red",
];

try await ditto.store.execute(
  query:"""
  INSERT INTO cars
  DOCUMENTS (:document)
  ON ID CONFLICT DO UPDATE
  """,
  arguments: [ "document": document ]);
ditto.store.execute(
  query = "INSERT INTO cars DOCUMENTS (:car) ON ID CONFLICT DO UPDATE",
  arguments = mapOf("car" to mapOf(
    "_id" to "123",
    "color" to "red"
  )))
const document = {
  _id: "123",
  color: "red",
};

await ditto.store.execute(`
  INSERT INTO cars
  DOCUMENTS (:document)
  ON ID CONFLICT DO UPDATE`,
  { document }
);
interface Car {
  _id: string;
  color: string;
}

const document: Car = {
  _id: "123",
  color: "red",
};

await ditto.store.execute(`
  INSERT INTO cars
  DOCUMENTS (:document)
  ON ID CONFLICT DO UPDATE`,
  { document }
);
import static com.ditto.java.serialization.DittoCborSerializable.buildDictionary;

var document = buildDictionary()
    .put("_id", "123")
    .put("color", "red")
    .build();

// This try-with-resources block auto-closes the DittoQueryResult
try (DittoQueryResult result = ditto.getStore().execute(
        "INSERT INTO cars VALUES (:document) ON ID CONFLICT DO MERGE",
        buildDictionary().put("document", document).build()
    ).toCompletableFuture().join()) {
    ...
}
var args = new Dictionary<string, object> {
  "document", new { _id = "123" , color = "red" }
};

await ditto.Store.ExecuteAsync(
  "INSERT INTO cars"
+ " DOCUMENTS (:document) ON ID CONFLICT DO UPDATE",
  args);
std::map<std::string, std::map<std::string, std::string>> args;
args["document"] = {{"_id", "123"},{"color", "red"}};

ditto.get_store().execute(
  "INSERT INTO cars DOCUMENTS (:document) ON ID CONFLICT DO UPDATE",
  args);
#[derive(Serialize)]
struct Args {
  document: Car,
}
struct Car {
  _id: String,
  color: String
}

// ...

let args = Args {
  document: Car {
    _id: "123".to_string(),
    color: "red".to_string()
  },
};

ditto.store().execute((
  "INSERT INTO cars DOCUMENTS (:document) ON ID CONFLICT DO UPDATE",
  args,
)).await?;
final document = {
  "_id": "123",
  "color": "red",
};

await ditto.store.execute("""
  INSERT INTO cars
  DOCUMENTS (:document)
  ON ID CONFLICT DO UPDATE""",
  arguments: {"document": document},
);
result, err = ditto.Store().Execute(
	"INSERT INTO cars DOCUMENTS (:document) ON ID CONFLICT DO UPDATE",
	ditto.QueryArguments{
		"document": ditto.Document{
			"_id":   "123",
			"color": "red",
		},
	},
)
if err != nil {
    return err
}
defer result.Close()  // cleanup

Nested MAPs

If you need to represent and organize highly complex data in a hierarchical structure, consider embedding a MAP within another MAP to establish a parent-child relationship within a document as follows. In 4.11+ with DQL_STRICT_MODE=false, collection definitions are no longer required. Read more about strict mode.
ALTER SYSTEM SET DQL_STRICT_MODE=false
Once Strict Mode is disabled, you can use the INSERT operation to add a new document with a nested map structure.

let arguments: [String: Any] = [
  "newDocument": [
    "_id": "123",
    "top_map": [
      "nested_map": [
        "color": "blue"
      ]
    ]
  ]
];

await ditto.store.execute(
  query: """
  INSERT INTO your_collection_name
  VALUES (:newDocument)
  """,
  arguments: arguments);
val arguments = mapOf(
  "newDocument" to mapOf(
    "_id" to "123",
    "top_map" to mapOf(
      "nested_map" to mapOf(
        "color" to "blue"
      )
    )
  )
)

ditto.store.execute("""
  INSERT INTO your_collection_name
  VALUES (:newDocument)
  """,
  arguments)
const newDocument = {
  _id: "123",
  top_map: {
    nested_map: {
      color: "blue"
    }
  }
};

await ditto.store.execute(`
  INSERT INTO your_collection_name
  VALUES (:newDocument)`,
  { newDocument }
);
interface NestedMap {
  color: string;
}

interface TopMap {
  nested_map: NestedMap;
}

interface Document {
  _id: string;
  top_map: TopMap;
}

const newDocument: Document = {
  _id: "123",
  top_map: {
    nested_map: {
      color: "blue"
    }
  }
};

await ditto.store.execute(`
  INSERT INTO your_collection_name
  VALUES (:newDocument)`,
  { newDocument }
);
import static com.ditto.java.serialization.DittoCborSerializable.buildDictionary;

var nestedMap = buildDictionary()
    .put("color", "blue")
    .build();

var topMap = buildDictionary()
    .put("nestedMap", nestedMap)
    .build();

var newDocument = buildDictionary()
    .put("_id", "123")
    .put("topMap", topMap)
    .build();

// This try-with-resources block auto-closes the DittoQueryResult
try (DittoQueryResult result = ditto.getStore().execute(
        "INSERT INTO your_collection_name VALUES (:newDocument)",
        buildDictionary().put("newDocument", newDocument).build()
    ).toCompletableFuture().join()) {
    ...
}
var nestedMap = new {
color = "blue"
};
var topMap = new {
nestedMap = nestedMap
};
var args = new Dictionary<string, object>();
args.Add("newDocument", new { _id = newId, topMap = topMap })

using var result = await ditto.Store.ExecuteAsync(
"INSERT INTO your_collection_name "
+ " VALUES (:newDocument)",
args);
struct NestedMap {
std::string color;
};
struct TopMap {
NestedMap nestedMap;
};
struct Document {
std::string _id;
TopMap topMap;
};

// ...

std::map<std::string, Document> args;
args["newDocument"] = {"123", TopMap{NestedMap{"blue"}}};

ditto.get_store().execute(
"INSERT INTO your_collection_name"
+ " VALUES (:newDocument)",
args);
#[derive(Serialize)]
struct Args {
    newDocument: Document,
}

#[derive(Serialize)]
struct Document {
    _id: String,
    topMap: TopMap
}

#[derive(Serialize)]
struct TopMap {
    nestedMap: NestedMap
}

#[derive(Serialize)]
struct NestedMap {
    color: String
}

// ...

let args = Args {
    newDocument: Document {
        _id: "123".to_string(),
        topMap: TopMap {
            nestedMap: NestedMap {
                color: "blue".to_string(),
            },
        },
    },
};

ditto.store().execute(
    "INSERT INTO your_collection_name VALUES (:newDocument)",
    args,
).await?;
final newDocument = {
  "_id": "123",
  "top_map": {
    "nested_map": {
      "color": "blue",
    },
  },
};

await ditto.store.execute("""
  INSERT INTO your_collection_name
  VALUES (:newDocument)""",
  arguments: {"newDocument": newDocument},
);
result, err := ditto.Store().Execute(
	"INSERT INTO your_collection_name VALUES (:newDocument)",
	ditto.QueryArguments{
		"newDocument": ditto.Document{
			"_id": "123",
			"top_map": map[string]any{
				"nested_map": map[string]any{
					"color": "blue",
				},
			},
		},
	},
)
if err != nil {
    return err
}
defer result.Close()  // cleanup