Escribir datos
Cypher en NamiDB soporta las cláusulas de escritura estándar de
openCypher 9 / GQL: CREATE, MERGE, SET, REMOVE, DELETE,
DETACH DELETE. Cada statement de escritura se persiste antes de
que la llamada retorne (WAL append + manifest CAS). En v0 no hay
BEGIN / COMMIT explícitos; la unidad de atomicidad es el statement.
Consulta RFC-009 para el modelo de ejecución.
CREATE
Crea nodos y relaciones. Las properties pueden ser literales o $param.
CREATE (a:Person {name: 'Alice', age: 30})CREATE (a:Person {name: 'Alice'})-[:KNOWS {since: 2020}]->(b:Person {name: 'Bob'})CREATE después de un MATCH encadena ambos bindings en el patrón
nuevo:
MATCH (a:Person {name: 'Alice'}), (b:Person {name: 'Bob'})CREATE (a)-[:KNOWS {since: 2020}]->(b)Una consulta solo-escritura (sin MATCH previo) arranca con un row
driver implícito — el mismo patrón que usa UNWIND.
MERGE
Upsert. Si el patrón matchea, devuelve los nodos / relaciones existentes; si no matchea, crea el patrón.
MERGE (p:Person {name: 'Alice'})ON CREATE SET p.firstSeen = $now, p.lastSeen = $nowON MATCH SET p.lastSeen = $nowEn v0, MERGE acepta una sola pattern part (sin patrones multi-parte).
MERGE (a:A:B {...}) multi-label es rechazado en tiempo de parse con
E007_MergeMultiLabel.
Concurrencia: MERGE se apoya en el invariante
single-writer-per-namespace para la serialización. Con un solo writer
por namespace, dos MERGE concurrentes contra la misma clave se
linealizan por el mutex del writer.
SET
Muta properties o agrega labels.
Asignación de property:
MATCH (p:Person {name: 'Alice'})SET p.age = 31Reemplazar el map de properties completo:
MATCH (p:Person {name: 'Alice'})SET p = {name: 'Alice', age: 31, country: 'MX'}Merge de un map parcial (solo las claves listadas cambian):
MATCH (p:Person {name: 'Alice'})SET p += {age: 31, country: 'MX'}Agregar labels:
MATCH (p:Person {name: 'Alice'})SET p:Employee:ManagerREMOVE
El inverso de SET. Quita properties o labels.
MATCH (p:Person {name: 'Alice'})REMOVE p.countryMATCH (p:Person {name: 'Alice'})REMOVE p:ManagerDELETE y DETACH DELETE
DELETE aplica un tombstone a un nodo o relación. Un DELETE directo
contra un nodo que todavía tiene aristas falla con un mensaje
explícito ExecError::Mutation que sugiere usar DETACH DELETE:
MATCH (p:Person {name: 'Alice'})DELETE p -- falla si Alice tiene aristas incidentesDETACH DELETE enumera las aristas incidentes a través de cada
edge_type en el schema del manifest, las tombstone-a, y después
tombstone-a el nodo:
MATCH (p:Person {name: 'Alice'})DETACH DELETE p -- elimina a Alice y cada arista que la tocaBorrar una arista directamente funciona sin DETACH:
MATCH (a:Person {name: 'Alice'})-[r:KNOWS]->(b:Person {name: 'Bob'})DELETE rUNWIND para escrituras en bulk
UNWIND expande una lista de parámetros a filas, que CREATE luego
materializa. Es el camino idiomático de Cypher para inserts masivos:
UNWIND $people AS pCREATE (:Person {name: p.name, age: p.age})client.cypher( "UNWIND $people AS p CREATE (:Person {name: p.name, age: p.age})", params={"people": [ {"name": "Alice", "age": 30}, {"name": "Bob", "age": 25}, {"name": "Carol", "age": 42}, ]},)Para ingesta de alto volumen, la API de staging en Python
(client.merge_nodes / client.merge_edges) es más rápida — agrupa
las mutaciones detrás de un solo round-trip del mutex de tokio por
llamada. Consulta Librería Python.
Auto-commit y el write outcome
Cada statement de escritura corre a través de execute_write, que:
- Recorre el plan de arriba a abajo, llamando
upsert_node/upsert_edge/tombstone_*contra elWriterSessionpor fila. - Llama automáticamente
writer.commit_batch().awaitantes de retornar.
El valor de retorno trae un resumen de contadores:
WriteOutcome { rows: ..., nodes_created: u64, edges_created: u64, nodes_deleted: u64, edges_deleted: u64, properties_set: u64,}Los contadores incrementan por operación, no por cambio neto de estado
(así que SET p.x = p.x cuenta como un properties_set). Los
contadores se exponen en el envelope HTTP como write_outcome —
consulta la API HTTP.
Read-your-own-writes (todavía no)
Dentro de un solo statement, las escrituras no son visibles a las lecturas que vienen después en el mismo plan tree. Ejemplo:
CREATE (a:Person {name: 'Ada'})MATCH (p:Person) RETURN p.nameEl MATCH corre contra el snapshot fijado antes del CREATE.
Workaround: divide en dos statements. Las escrituras Cypher hacen
auto-commit, así que el segundo statement (o la siguiente llamada a
Client.cypher) ve el nodo nuevo.
RFC-009 documenta por qué y traza el camino hacia un modelo transaccional futuro.
Siguientes pasos
- Leer datos —
MATCH,WHERE,RETURN, agregaciones. - Operadores y funciones — la referencia completa de operadores y funciones integradas.
- Subset soportado — la porción exacta de openCypher / GQL que acepta el parser.