Search code examples
node.jsneo4jcypherneo4j-driver

Clarify different behaviour of neo4j and neo4j-driver


I have a rudimentary database that has just a couple of nodes and relationships. When I run a match (n) return n command on the local web client provided with neo4j it returns all the nodes and relationships that's in the database, as seen in the picture below.

neo4j web client

However when I run exactly the same command in a node.js project using the neo4j-driver module, it only returns the three nodes and none of the two relationships are included.

After a little bit of fiddling with it, I noticed that to retrieve the relationships too, I must issue something like match (n)-[r]-(m) return *. My first question is why is there such a difference? Is the local web client just trying to do a bit more to help the user?

Furthermore I find the returned records object a little bit confusing. Running this match (n)-[r]-(m) return * command returns 4 items in the result.records object out of which 2-2 are almost identical pair-wise. In a simplified view this is what it returns:

item 0: [Jack node, Jill node, Jack -> Jill relationship]
item 1: [Jill node, Jack node, Jack -> Jill relationship]
item 2: [George node, Jill node, George -> Jill relationship]
item 3: [Jill node, George node, George -> Jill relationship]

So items 0 and 1 of the result.records object differ only by the order of their elements. Same for items 2 and 3.

Question two is what am I supposed to do with this if I want to display the graph on a web page? Look for unique IDs of the nodes and relationships in all the different combinations returned?

Question three: maybe there's a better way to achieve what I'm trying to do?


Solution

  • The Neo4j web browser is indeed just trying to be helpful and the visualization will connect nodes if they have relationships between them (there's an option to turn this behaviour off btw). However, the resultset will not contain those if you didn't ask for them (as it shouldn't). Look on the other reponse tabs (table, text, code) in the browser to see the actual resultset.

    This query may help you :

    match p=(n)-[r]-(m) return p
    

    But yes, you are correct, you will have to unpack the result in your application in order to be able to do your own interpretation. It is a case of the you get what you asked for problem that quite a few Neo4j users face. It is due to the fact that Cypher can return quite a few different things (tabular results, nodes, nodes and relationships, paths, subgraphs, ...) and the driver has to provide for all of them.

    Have a look at the code tab in the browser to get a feel of what your application will have to work with (what you actually get depends on your application language of choice). It's not very difficult but it does require a bit of getting used to.

    Hope this helps.

    Regards, Tom

    P.S. Doubles in the results are to be expected with such generic queries. Neo4j does pattern matching and your pattern does not have a direction on the relationship nor does it have labels or relationshiptypes. That's going to return quite a few matches where for example (jill)-[:nominated]-(jack) but obviously it also matches (jack)-[:nominated]-(jill). Both match the pattern. Using DISTINCT may help a bit but you really should be more explicit in the pattern.