3
votes

I am very sorry if this question has been asked before. It seems more basic than it should have been.

I'm trying to evaluate Neo4j for my employer. I had no involvement in setting up the eval environment and it appears to be minimal. I only have the web-based browser & cypher to get anything done. I can't even load a file to the server in order to load by CSV.

And I'm having a lot of trouble loading test data. I chose to use data warehouse metadata as my subject and add :table nodes and then :model nodes (that catalog the diagrams that the tables [APPEAR_ON]). And I should point out ... the APPEAR_ON relationships are sourced from a many-to-many relationship in the RDMS: A model holds many tables; a table can appear on multiple models. So I don't think I'm able to load the relationships at the same time as the nodes. I don't know what else to try other than to load all nodes and then all relationships. COMMENT?

  • I can load :table nodes and :model nodes just fine by pulling together the many CREATE/MERGE statements on separate lines and pasting them into the cypher query tool in the browser.
  • I also created indexes / uniqueness constraints for these labels after I created the nodes. (I loaded ID properties for each.)
  • BUT I CANNOT FIGURE OUT HOW TO CREATE THE RELATIONSHIPS using the multiple-statements approach. MATCH (t:table),(m:model) WHERE t.tid = "T0525" AND m.mid = "M001" CREATE (t)-[R00864:APPEARS_IN]->(m) MATCH (t:table),(m:model) WHERE t.tid = "T0526" AND m.mid = "M001" CREATE (t)-[R00865:APPEARS_IN]->(m)

Unfortunately, I can only make this work one at a time by including RETURN at the end of the statement. When I send multiple statements, I get an error that says I need to include a WITH statement between the CREATE of the first statement and the MATCH of the second statement.

Many thanks for your ideas!

1

1 Answers

8
votes

For formatting queries, check the top right box of the cypher refcard. Your queries are mostly right, but you're trying to do too much I think. You can't do multiple match/create blocks like that, without a with.

So one way to rewrite this is to do it as two queries:

MATCH (t:table),(m:model) WHERE t.tid = "T0525" AND m.mid = "M001" CREATE (t)-[R00864:APPEARS_IN]->(m);

MATCH (t:table),(m:model) WHERE t.tid = "T0526" AND m.mid = "M001" CREATE (t)-[R00865:APPEARS_IN]->(m);

But you're "re-matching" that same model twice. So you could also do this:

MATCH  (t1:table { tid: "T0525" }), 
       (m:model {mid: "M001"}), 
       (t2:table { tid: "T0526 })
CREATE (t1)-[R00864:APPEARS_IN]->(m),
       (t2)-[R00865:APPEARS_IN]->(m);

Note that I eliminated the WHERE by adding the match criteria in as match properties, then I used a comma to create two separate CREATE statements without a separate query, just as you can do the same to do multiple matches.