MERGE

Предложение MERGE гарантирует наличие в графе указанного шаблона — либо путём сопоставления существующих данных, либо их создания.

MERGE либо находит существующую вершину, либо создаёт новые данные. Оно объединяет поведение MATCH и CREATE.

Примечание!
Ограничения на MERGE в YMatrix AGE:

  1. Синтаксис ON MATCH SET и ON CREATE SET не поддерживается.

    MERGE (n:node {name: 'Lisa'}) ON MATCH SET n.age = 23  
    -- ОШИБКА: синтаксическая ошибка около "ON"  
  2. Объединение MERGE с другими операциями записи (CREATE, SET) через WITH вызывает ошибку.

  3. При цепочке MERGE с CREATE или SET через WITH для передачи привязанных переменных возникают ошибки распределённых транзакций:

    
    -- Ошибка  
    CREATE (n) WITH n AS a MERGE (a)-[:e]->()  
    -- ОШИБКА: AssignTransactionId() вызван процессом Segment Reader  

-- Ошибка
CREATE (n {i : 1}) SET n.i = 2 MERGE ({i: 2})
-- ОШИБКА: AssignTransactionId() вызван процессом Segment Reader



**Рекомендация:** Разделите `MERGE` и другие операции записи на отдельные запросы Cypher.

Например, можно задать требование, чтобы в графе присутствовала вершина пользователя с определённым именем. Если вершины с таким именем нет, она будет создана, а её свойство name установлено. При применении MERGE к полному шаблону поведение является «всё или ничего»: либо весь шаблон совпадает целиком, либо создаётся целиком. MERGE не выполняет частичное повторное использование существующих шаблонов. Для частичного сопоставления разбейте шаблон на несколько предложений MERGE.

Как и MATCH, MERGE может находить несколько вхождений шаблона. Если найдено несколько совпадений, все они передаются в последующие этапы запроса.

Подготовка данных

SELECT * FROM cypher('graph_name', $$
CREATE (A:Person {name: "Charlie Sheen", bornIn: "New York"}),
    (B:Person {name: "Michael Douglas", bornIn: "New Jersey"}),
    (C:Person {name: "Rob Reiner", bornIn: "New York"}),
    (D:Person {name: "Oliver Stone", bornIn: "New York"}),
    (E:Person {name: "Martin Sheen", bornIn: "Ohio"})
$$) AS (result agtype);

Объединение вершин

Объединение вершины с меткой

Чтобы объединить вершину с меткой, укажите шаблон, содержащий одну вершину с меткой.

Запрос

SELECT * FROM cypher('graph_name', $$
MERGE (v:Critic)
RETURN v
$$) AS (v agtype);

Если существует вершина с меткой Critic, она возвращается. В противном случае создаётся и возвращается новая вершина Critic.

v
{id: 0; label: 'Critic'; properties: {}}::vertex
1 строка возвращена

Объединение одной вершины со свойствами

Объедините вершину, у которой не все свойства совпадают с существующей.

Запрос

SELECT * FROM cypher('graph_name', $$
MERGE (charlie {name: 'Charlie Sheen', age: 10})
RETURN charlie
$$) AS (v agtype);

Если существует вершина со всеми указанными свойствами, она возвращается. В противном случае создаётся и возвращается новая вершина с именем 'Charlie Sheen'.

v
{id: 0; label: 'Actor'; properties: {name: 'Charlie Sheen', age: 10}}::vertex
1 строка возвращена

Объединение одной вершины с меткой и свойствами

Объедините вершину, ограниченную как меткой, так и свойствами, совпадающими с существующей вершиной.

Запрос

SELECT * FROM cypher('graph_name', $$
MERGE (michael:Person {name: 'Michael Douglas'})
RETURN michael.name, michael.bornIn
$$) AS (Name agtype, BornIn agtype);

'Michael Douglas' совпадает с существующей вершиной Person, и запрос возвращает её свойства name и bornIn.

Name BornIn
"Michael Douglas" "New Jersey"
1 строка возвращена