3

I am setting up a time-based graph database, around the following design principle:

enter image description here

I have a program which is supposed create new time-points (when relevant) in the database. I find the relevant nodes using a binary searchand then attempt to delete existing relationships (if needed) and create new relationships.

The two nodes (204452 and 203838) that I am trying to connect exist and can be retrieved using the following syntax:

MATCH (y1:Year)-[:CONTAINS_MONTH]->(m1:Month)-[:CONTAINS_DAY]->(d1:Day)-[:CONTAINS_TIMEPOINT]->(t1:Time)
where (y1.year='2017' AND m1.month='02' AND d1.day='28' AND t1.time='204452')
return y1, m1, d1, t1

The above queries yield the following subgraphs (showing that the individual queries work, right?)

enter image description here enter image description here

However, when I try to create the connection using the following query:

MATCH (y1:Year {year:'2017'})-[:CONTAINS_MONTH]->(m1:Month {month:'02'})-[:CONTAINS_DAY]->(d1:Day {day:'28'})-[:CONTAINS_TIMEPOINT]->(t1:Time {time:'203838'}),
(y2:Year {year:'2017'})-[:CONTAINS_MONTH]->(m2:Month {month:'02'})-[:CONTAINS_DAY]->(d2:Day {day:'28'})-[:CONTAINS_TIMEPOINT]->(t2:Time {time:'204452'})
CREATE (t1)-[:NEXT_TIMEPOINT]->(t2)

Nothing happens and the Neo4j website frontend (that I was using to try and identify the issue) gives a warning about a cartesian product. I will admit that I have only recently started working with Neo4j and therefore I will mention what I think what the above query should do:

The first MATCH line defines and runs the first sub-query, returning the 203838 subgraph. The second MATCH line defines and runs the second subquery, returning the 204452 subgraph. Lastly, the CREATE line creates a relationship between the two time nodes acquired via the above sub-queries.

However, as there is nothing happening I assume that my understanding of the above query is wrong and I would like to know Q1. what it actually does and Q2. what would be the correct way to do this?

Bas Jansen
  • 3,273
  • 5
  • 30
  • 66

1 Answers1

4

About the warning related to the cartesian product: this happens because you are MATCHing two nodes without any relations between them. Take a look here and here.

To solve this warning use two MATCHes instead of one. I simulated your scenario here. This is the query to crate the initial dataset:

CREATE (y1:Year {year:'2017'})-[:CONTAINS_MONTH]->(m1:Month {month:'02'})-[:CONTAINS_DAY]->(d1:Day {day:'28'})-[:CONTAINS_TIMEPOINT]->(t1:Time {time:'203838'})
CREATE (y2:Year {year:'2017'})-[:CONTAINS_MONTH]->(m2:Month {month:'02'})-[:CONTAINS_DAY]->(d2:Day {day:'28'})-[:CONTAINS_TIMEPOINT]->(t2:Time {time:'204452'})

After (note the two MATCH statements):

MATCH (y1:Year {year:'2017'})-[:CONTAINS_MONTH]->(m1:Month {month:'02'})-[:CONTAINS_DAY]->(d1:Day {day:'28'})-[:CONTAINS_TIMEPOINT]->(t1:Time {time:'203838'})
MATCH (y2:Year {year:'2017'})-[:CONTAINS_MONTH]->(m2:Month {month:'02'})-[:CONTAINS_DAY]->(d2:Day {day:'28'})-[:CONTAINS_TIMEPOINT]->(t2:Time {time:'204452'})
CREATE (t1)-[:NEXT_TIMEPOINT]->(t2)

The result:

Result

Bruno Peres
  • 15,845
  • 5
  • 53
  • 89
  • Thank you for the answer, and the links to the other questions/answers especially! – Bas Jansen Aug 14 '17 at 11:49
  • @BasJansen you are welcome! The relationship between the timepoints is being created now? – Bruno Peres Aug 14 '17 at 11:52
  • Yes it is. I am now finalizing the `if/else` structure that leads to these queries as some relationships have now been duplicated but that should be quite straight forward. – Bas Jansen Aug 14 '17 at 11:53
  • 1
    @BasJansen If you need relationships not to be duplicates you can try using a MERGE instead of CREATE. That is, change the last line to: `MERGE (t1)-[:NEXT_TIMEPOINT]->(t2)` – Bruno Peres Aug 14 '17 at 11:58