Neo4j Cypher запрашивает ОБЪЯСНЕНО идентично, но предупреждения генерируются только для одного - PullRequest
1 голос
/ 29 мая 2019

У меня есть csv файл, содержащий отношение один-ко-многим, где каждый элемент типа A состоит из одного или нескольких элементов типа B, но каждый элемент B относится только к одному элементу тип A.

Пример:

   A   |  B   
-------------
   a1  |  b1
   a1  |  b2
   a1  |  b3
   a2  |  b4

Я уже создал узел в графе neo4j, и теперь я хочу создать ребро для этих отношений.

Я думал, что этот запрос

LOAD CSV WITH HEADERS FROM "file:///file.csv" AS row
WITH row
MATCH (n:A {A_ID: row.a_id}), (t:B {BID : row.b_id})
MERGE (n)-[:HAS_CONNECTION]->(t);

но Neo4j выдает следующее предупреждение:

Этот запрос строит декартово произведение между несвязанными образцами. Если часть запроса содержит несколько отключенных шаблонов, это построит декартово произведение между всеми этими частями. Это может производить большой объем данных и замедлить обработку запросов. В то время как время от времени, возможно, будет возможно переформулировать запрос, который избегает использования этого кросс-продукта, возможно, путем добавления отношения между различными частями или с помощью OPTIONAL MATCH (identifier is: (t))

Поэтому я изменил его на:

LOAD CSV WITH HEADERS FROM "file:///file.csv" AS row
WITH row
MATCH (t:B {BID : row.b_id})
WITH row, t
MATCH (n:A {AID: row.a_id})
MERGE (n)-[:HAS_CONNECTION]->(t);

и Neo4j не жалуется.

Однако, если я EXPLAIN оба запроса, результат будет одинаковым.

Неужели neo4j бесполезно жаловаться на первый запрос или есть эффективные преимущества со вторым?

1 Ответ

2 голосов
/ 29 мая 2019

Хотя предупреждение верно, запросы строят декартово произведение, что в данном случае хорошо, так как это именно то, что вы хотите, n и t, даже если они не подключены, и количество элементов будет в любом случае быть низким (вероятно, 1, если это уникальные узлы).

Не обращайте внимания на предупреждение и сохраняйте свой первый запрос, когда вы делаете что-то вроде этого, где ожидаемое количество узлов каждой из этих переменных равно 1 или, по крайней мере, мало.

Что касается того, почему предупреждение не появляется во втором плане, это, вероятно, всего лишь ограничение на то, что рассматривается для создания предупреждения. Они все еще эквивалентны, и то же самое относится.

И просто отметьте реальную причину предупреждения, это чтобы вы не делали что-то вроде:

MATCH (a:A), (b:B)

или аналогичный, где вы в конечном итоге получите декартово произведение между всеми узлами одного типа и всеми остальными. Если вы сузите их до конкретных свойств (особенно уникальных), то это будет просто декартово произведение 1x1, никаких проблем.

...