4

When writing a query to add relationships to existing nodes, it keeps me warning with this message:

"This query builds a cartesian product between disconnected patterns. If a part of a query contains multiple disconnected patterns, this will build a cartesian product between all those parts. This may produce a large amount of data and slow down query processing. While occasionally intended, it may often be possible to reformulate the query that avoids the use of this cross product, perhaps by adding a relationship between the different parts or by using OPTIONAL MATCH (identifier is: (e))"

If I run the query, it creates no relationships. The query is:

match   
    (a{name:"Angela"}),
    (b{name:"Carlo"}),
    (c{name:"Andrea"}),
    (d{name:"Patrizia"}),
    (e{name:"Paolo"}),
    (f{name:"Roberta"}),
    (g{name:"Marco"}),
    (h{name:"Susanna"}),
    (i{name:"Laura"}),
    (l{name:"Giuseppe"})


create  
    (a)-[:mother]->(b),
    (a)-[:grandmother]->(c), (e)-[:grandfather]->(c), (i)-[:grandfather]->(c), (l)-[:grandmother]->(c),
    (b)-[:father]->(c),
    (e)-[:father]->(b),
    (l)-[:father]->(d),
    (i)-[:mother]->(d),
    (d)-[:mother]->(c),
    (c)-[:boyfriend]->(f),
    (g)-[:brother]->(f),
    (g)-[:brother]->(h),
    (f)-[:sister]->(g), (f)-[:sister]->(h)

Can anyone help me?

PS: if I run the same query, but with just one or two relationships (and less nodes in the match clause), it creates the relationships correctly.

sirdan
  • 1,018
  • 2
  • 13
  • 34
  • 2
    Aren't you using labels for your nodes? it's slowing down your query process really hard, because if you don't have any Label, every query will have to look at the entire dataset to find the property you are looking for. – Supamiu Nov 19 '15 at 09:08
  • I didn't add any labels, I try immediately and let you know – sirdan Nov 19 '15 at 09:19
  • same result, nothing changed with labels. – sirdan Nov 19 '15 at 09:22
  • I'm reinstalling Neo4j (fresh new computer) to try your query, and I'll tell you what's wrong in an answer (I'll reply in max 1h). – Supamiu Nov 19 '15 at 09:29

2 Answers2

4

What is wrong here?

  • First of all, as I mentionned in my comments, you don't have any Labels, it's a really bad practice because Labels are useful to match properties in a certains dataset (if you match "name" property, you don't want to match it on a node who doesn't have a name, Labels are here for that.

  • The second problem is that your query doesn't know how many nodes it will get before it does. It means that if you have 500 000 nodes having name : "Angela" and 500 000 nodes having name : "Carlo", you will create one relation from each Angela node, going on each Carlo, that's quite a big query (500 000 * 500 000 relations to create if my maths aren't bad). Cypher is giving you a warning for that.

  • Cypher will still tell you this warning because you aren't using Unique properties to match your nodes, even with Labels, you will still have the warning.

Solution?

  • Use unique properties to create and match your nodes, so you avoid cartesian product.

  • Always use labels, Neo4j without labels is like using one giant table in SQL to store all of your data.

If you want to know how your query will run, use PROFILE before your query, here is the profile plan for your query:

Cypher execution plan

Community
  • 1
  • 1
Supamiu
  • 8,501
  • 7
  • 42
  • 76
  • Labels added As regards your second comment, it won't be bad just because it's a small dataset to learn Cypher, but I got your point. – sirdan Nov 19 '15 at 10:35
  • here is the create clause which created the nodes; create (n:Person{name:"Carlo", born:1992, city:"Roma"}), (n1:Person{name:"Andrea", born:1962, city:"Roma"}), (n2:Person{name:"Angela", born:1931, city:"Tivoli"}), (n3:Person{name:"Paolo", born:1929, city:"Tivoli"}), (n4:Person{name:"Laura", born:1936, city:"Caposele"}), (n5:Person{name:"Marco", born:1934, city:"Sant'Angelo dei Lombardi"}), (n6:Person{name:"Giuseppe", born:1997, city:"Paternò"}), (n7:Person{name:"Patrizia", born:1991, city:"Paternò"}) – sirdan Nov 19 '15 at 10:35
  • I already created the nodes needed, the only thing you need is to create Unique constraint on an id property, or anything else unique (national ID, security ID, etc...). Else, your warning will still be here, I mentionned it in my answer, with a documentation link. – Supamiu Nov 19 '15 at 10:40
  • ok, thanks in advance for your kindness. Now I have to leave this work but I'm going to try what you suggested and I'll let you know – sirdan Nov 19 '15 at 11:41
0

Does every single one of those name strings exist? If not then you're not going to get any results because it's all one big match. You could try changing it to a MERGE.

But Supamiu is right, you really should have a label (say Person) and an index on :Person(name).

Brian Underwood
  • 10,746
  • 1
  • 22
  • 34
  • Here is the query which created the nodes in my db: create (n:Person{name:"Carlo", born:1992, city:"Roma"}), (n1:Person{name:"Andrea", born:1962, city:"Roma"}), (n2:Person{name:"Angela", born:1931, city:"Tivoli"}), (n3:Person{name:"Paolo", born:1929, city:"Tivoli"}), (n4:Person{name:"Laura", born:1936, city:"Caposele"}), (n5:Person{name:"Marco", born:1934, city:"Sant'Angelo dei Lombardi"}), (n6:Person{name:"Giuseppe", born:1997, city:"Paternò"}), (n7:Person{name:"Patrizia", born:1991, city:"Paternò"}) So I also added the labels as you suggested. So name exists – sirdan Nov 19 '15 at 10:31