Ger
Ger

Reputation: 754

Connections between friends in cypher / Neo4j

I have a graph I'm trying to query, essentially people can contact other people.

I'm looking to run a cypher query which starts with a person and returns all people they've contacted, and any contact between their contacts.

This is the query I've started with

start n = node:node_auto_index(name = "TOM") MATCH (n)-[r]-(m) RETURN *

In the neo4j web interface this returns Tom, anybody tom contacted and any relationships between tom's contacts, in all 20 nodes and 32 relationships. The results are output in the format m, n r (node, node, relationship)

However when I run

start n = node:node_auto_index(name = "TOM") MATCH (n)-[r]-(m) RETURN count(*)

it says there are only 26 relationships and excludes any between tom's contacts.

I'm pulling the results into a d3.js visualisation, so ideally the results will still be output in a format similar to node, node, relationship (i.e. each related pair on one line).

EDIT: More detail

I have a graph with users who can contact one another. I want to be able to query for a user and get back all users he has contacted, and any contact between users he has contacted. Similar to LinkedinLabs Inmaps

enter image description here

But I need the output in a format that I can relatively straightforwardly use in a d3 forced directed.

For example if the output had, for example

 (Tom) - (Tom's friend) - (Tom's Friend's Friend)

it would be much easier for this to be broken into

 (Tom) - (Tom's friend)
 (Tom's Friend) - (Tom's Friend's Friend)

Since this d3 graph expects and input of a Nodes object and a Links object.


EDIT

From uklas' answer, this got it working.

start n = node:node_auto_index(name = "Tom")
MATCH (n)-[r]-(m)
RETURN n as person, m as personas_fr, r
UNION
start n = node:node_auto_index(name = "Tom")
MATCH (a)-[r1]-(n)-[r2]-(m), (a)-[r]-(m)
RETURN a as person, m as personas_fr, r

Upvotes: 0

Views: 1158

Answers (1)

ulkas
ulkas

Reputation: 5918

there might be multiple contact relationships, ie some people had been contacted by Tom several times. using count(*) you are aggregating such contacts, those it returns only unique contacted people. using just * you are returning everything that is being matched.

if you would write more about your goal, and what you wanna do (ie put a question), i could also add some suggestion on how to proceed.

update

unfortunately i'm not familiar with d3 format, but maybe this will help:

    start n = node:node_auto_index(name = "TOM")
    MATCH (n)-[r]-(m)
    RETURN n as person, m as personas_fr
    UNION 
    start n = node:node_auto_index(name = "TOM")
    MATCH (n)-[r]-(m), (m)-[r2]-(m2)
    WHERE Id(n) <> Id(m2)
    RETURN m as person, l as personas_fr

returns data in format

 (Tom) - (Tom's friend1)
 (Tom) - (Tom's friend2)
 (Tom) - (Tom's friend3)
 (Tom's Friend1) - (Tom's Friend's Friend)
 (Tom's Friend1) - (Tom's Friend's Friend)
 (Tom's Friend1) - (Tom's Friend's Friend)
 (Tom's Friend2) - (Tom's Friend's Friend)
 (Tom's Friend2) - (Tom's Friend's Friend)
 (Tom's Friend3) - (Tom's Friend's Friend)
 (Tom's Friend3) - (Tom's Friend's Friend)

Upvotes: 2

Related Questions