Return nodes together with relations - neo4j

I'm playing with Cypher and Neo4j a bit and I created a simple graph:
CREATE (j: person { name: "james" })
CREATE (m: person { name: "mary" })
CREATE (j)<-[:friends_with]-(m)
If I return all the nodes:
MATCH (m) RETURN m
in the graph view I get:
but the response JSON is:
[
{
"keys": [
"m"
],
"length": 1,
"_fields": [
{
"identity": {
"low": 3,
"high": 0
},
"labels": [
"person"
],
"properties": {
"name": "james"
}
}
],
"_fieldLookup": {
"m": 0
}
},
{
"keys": [
"m"
],
"length": 1,
"_fields": [
{
"identity": {
"low": 4,
"high": 0
},
"labels": [
"person"
],
"properties": {
"name": "mary"
}
}
],
"_fieldLookup": {
"m": 0
}
}
]
which contains the list of nodes, but no information about the relationship between nodes.
Is it possible to also get the full graph/the relationship between nodes if certain returned nodes have relationships defined between one another?

If you want to retrieve relationship information, you must request it in your Cypher request.
For example, if you want to retrieve all the nodes with a friends_with relationship
MATCH (a:person)-[r:friends_with]-(b:person) RETURN a,r,b
Thus you will recover the nodes and the relationships of the people concerned.
Of course, you can adapt this query, depending on whether you want to know only the original node, only have the relation, etc ...
If you want to get ALL the nodes with an is_friends relation:
MATCH (a)-[r:friends_with]-() RETURN a,r
So you will turn all the node and the relationship too

Related

Issue in Cypher Query - org.neo4j.internal.kernel.api.exceptions.EntityNotFoundException

I am performing below steps using cypher query. I am getting error in step 3. I have listed all steps below. Please help me to achieve expected output.
Step 1- Load data and define properties of nodes relationship
LOAD CSV WITH HEADERS FROM 'file://nodes_1Jan22_full_v2.csv' AS row
CREATE (n: Organisation {id: row.organisation, esg_index: toFloat(row.tone)});
LOAD CSV WITH HEADERS FROM 'file://edges_1Jan22_full_v2.csv' AS row
MERGE (src: Organisation {id: row.src})
MERGE (dst: Organisation {id: row.dst})
MERGE (src)-[:RELATE {freq: toInteger(row.relationship), sentiment: toFloat(row.avg_tone)}]->(dst);
Sample query and table structure
MATCH p=()-[r:RELATE]->() RETURN p LIMIT 1
{
"start": {
"identity": 18862,
"labels": [
"Organisation"
],
"properties": {
"id": "american university",
"esg_index": -3.005288932058546
}
},
"end": {
"identity": 20048,
"labels": [
"Organisation"
],
"properties": {
"id": "duke university",
"esg_index": -1.6810932825414502
}
},
"segments": [
{
"start": {
"identity": 18862,
"labels": [
"Organisation"
],
"properties": {
"id": "american university",
"esg_index": -3.005288932058546
}
},
"relationship": {
"identity": 0,
"start": 18862,
"end": 20048,
"type": "RELATE",
"properties": {
"sentiment": -4.367701625823974,
"freq": 250
}
},
"end": {
"identity": 20048,
"labels": [
"Organisation"
],
"properties": {
"id": "duke university",
"esg_index": -1.6810932825414502
}
}
}
],
"length": 1.0
}
Step 2- Create graph projection
CALL gds.graph.project(
'gdelt-analytics',
'Organisation',
'RELATE',
{
relationshipProperties: 'freq'
}
)
MATCH (org:Organisation {id: 'public health'})
CALL gds.pageRank.stream('gdelt-analytics', {
maxIterations: 100,
dampingFactor: 0.85,
sourceNodes: [org],
relationshipWeightProperty: 'freq'
})
YIELD nodeId, score
RETURN *
Current Output
Step 3- Attempt to color node based on property "esg_index" and edges based on property "sentiment" (Query that is throwing error)
CALL apoc.create.addLabels(n.esg_index, [apoc.text.upperCamelCase(n.id)]) YIELD node
RETURN *
Neo.ClientError.Procedure.ProcedureCallFailed
Failed to invoke procedure apoc.create.addLabels: Caused by: org.neo4j.internal.kernel.api.exceptions.EntityNotFoundException: Unable to load NODE with id -2.
Expected Output
Graph with nodes and edges colored. Nodes colored based on esg_index and edges colored based on sentiment
The APOC addLabels function takes either a list of nodes or their id, which can be found using ID(n), as its input. You are passing esg_index, that's why you might be getting this error:
Try this:
CALL apoc.create.addLabels(n, [apoc.text.upperCamelCase(n.id)]) YIELD node
RETURN *
It should work. Documentation link.
Update:
To add the label using esg_index, I think apoc.do.case function should do the trick for you. You can try something like this:
CALL apoc.do.case([
n IS NOT NULL AND n.esg_index = -5,
'SET n:DARK_RED RETURN n AS node',
n IS NOT NULL AND n.esg_index = 1,
'SET n:GREEN RETURN n AS node'
],
'RETURN n AS node',{n: n})
YIELD value
RETURN value.node AS node;

How to use ORDER BY and LIMIT on node children but not their parents? Cypher

I have a set of Author nodes. An Author node is the single parent of multiple Book nodes.
My goal: To print all Author nodes with no order and no limit, with each authors' first three books in alphabetical order.
Desired output: (let's pretend book names are a single letter)
[
{
"name" : "Leo Tolstoy",
"books": [
{ "name": "A" },
{ "name": "B" },
{ "name": "D" }
]
},
{
"name": "Charles Dickens",
"books": [
{ "name": "C" },
{ "name": "E" },
{ "name": "F" }
]
},
{
"name": "Oscar Wilde
...
]
My Problem:
I tried this:
MATCH(author:Author)
WITH author
OPTIONAL MATCH(author)-[:WROTE]->(book:Book)
WITH author, book
ORDER BY book.name
LIMIT 3
WITH author, collect(book) AS books
RETURN collect (
{
name: author.name,
books: books
}
);
But this gives:
[
{
"name" : "Leo Tolstoy",
"books": [
{ "name": "A" },
{ "name": "B" },
]
},
{
"name": "Charles Dickens",
"books": [
{ "name": "C" }
]
}
]
How could I achieve my desired output in Neo4j v3.5?
[EDITED]
This should work:
MATCH(author:Author)
OPTIONAL MATCH(author)-[:WROTE]->(book:Book)
WITH author, book.name AS bookName
ORDER BY bookName
WITH author, COLLECT({name: bookName})[..3] AS bookNames
RETURN COLLECT({name: author.name, books: bookNames}) AS result

How can I restore data from a previous result in the browser?

I have a query that I ran in the neo4j web browser:
MATCH p=(z)<-[*]-(a)-[:foo]->(b) WHERE b.value = "bar" return p
This returned a large number of connected nodes. Something happened that seems to have deleted all of these nodes (in a separate incident), but I still have the output of the old query. The code section of the browser has the response data listed:
...
"graph": {
"nodes": [
{
"id": "1148578",
"labels": [
"text"
],
"properties": {
"value": "bar",
"timestamp": 1478747946867
}
},
...
Is there a way for me to recreate all of this data from the output of an old query?
You could use apoc.load.json to do this. Note that this solution will not preserve the internal node ids. APOC is a procedure library that extends built-in Neo4j functionality.
Given the JSON file
{"graph": {
"nodes": [
{
"id": "32496",
"labels": [
"Person"
],
"properties": {
"born": 1967,
"name": "Carrie-Anne Moss"
}
},
{
"id": "32505",
"labels": [
"Movie"
],
"properties": {
"tagline": "Evil has its winning ways",
"title": "The Devil's Advocate",
"released": 1997
}
},
{
"id": "32494",
"labels": [
"Movie"
],
"properties": {
"tagline": "Welcome to the Real World",
"title": "The Matrix",
"released": 1999
}
},
{
"id": "32495",
"labels": [
"Person"
],
"properties": {
"born": 1964,
"name": "Keanu Reeves"
}
}
],
"relationships": [
{
"id": "83204",
"type": "ACTED_IN",
"startNode": "32495",
"endNode": "32505",
"properties": {
"role": "Kevin Lomax"
}
},
{
"id": "83183",
"type": "ACTED_IN",
"startNode": "32496",
"endNode": "32494",
"properties": {
"role": "Trinity"
}
},
{
"id": "83182",
"type": "ACTED_IN",
"startNode": "32495",
"endNode": "32494",
"properties": {
"role": "Neo"
}
}
]
}
}
}
We can recreate the graph using this query:
CALL apoc.load.json("https://dl.dropboxusercontent.com/u/67572426/small_movie_graph.json") YIELD value AS row
WITH row, row.graph.nodes AS nodes
UNWIND nodes AS node
CALL apoc.create.node(node.labels, node.properties) YIELD node AS n
SET n.id = node.id
WITH row
UNWIND row.graph.relationships AS rel
MATCH (a) WHERE a.id = rel.startNode
MATCH (b) WHERE b.id = rel.endNode
CALL apoc.create.relationship(a, rel.type, rel.properties, b) YIELD rel AS r
RETURN *

How to return relationship type with Neo4J's Cypher queries?

I am trying to get the relationship type of a very simple Cypher query, like the following
MATCH (n)-[r]-(m) RETURN n, r, m;
Unfortunately this return an empty object for r. This is troublesome since I can't distinguish between the different types of relationships. I can monkey patch this by adding a property like [r:KNOWS {type:'KNOWS'}] but I am wondering if there isn't a direct way to get the relationship type.
I even followed the official Neo4J tutorial (as described below), demonstrating the problem.
Graph Setup:
create (_0 {`age`:55, `happy`:"Yes!", `name`:"A"})
create (_1 {`name`:"B"})
create _0-[:`KNOWS`]->_1
create _0-[:`BLOCKS`]->_1
Query:
MATCH p=(a { name: "A" })-[r]->(b)
RETURN *
JSON RESPONSE BODY:
{
"results": [
{
"columns": [
"a",
"b",
"p",
"r"
],
"data": [
{
"row": [
{
"name": "A",
"age": 55,
"happy": "Yes!"
},
{
"name": "B"
},
[
{
"name": "A",
"age": 55,
"happy": "Yes!"
},
{},
{
"name": "B"
}
],
{}
]
},
{
"row": [
{
"name": "A",
"age": 55,
"happy": "Yes!"
},
{
"name": "B"
},
[
{
"name": "A",
"age": 55,
"happy": "Yes!"
},
{},
{
"name": "B"
}
],
{}
]
}
]
}
],
"errors": []
}
As you can see, I get an empty object for r, which makes it impossible to distinguish between the relationships.
NOTE: I am running Neo4J v.2.2.2
Use the type() function.
MATCH (n)-[r]-(m) RETURN type(r);
Added distinct.
MATCH (n)-[r]-(m) RETURN distinct type(r);

neo4j rest API resultDataContents:graph does not really returns one graph?

To make yet another d3 viewer, I'd like to get a graph out from a rest query.
In my understanding, stating 'resultDataContent':['graph'] would return a graph. Instead, it return a list of subgraphs and I need therefore to collect and distinct the nodes. Is there a way to get the full sub graph simply?
For example, I put these 4 nodes
CREATE (a:Person {name:'a'})
CREATE (b:Person {name:'b'})
CREATE (c:Person {name:'c'})
CREATE (d:Person {name:'d'})
CREATE (a)-[:KNOWS]->(b)
CREATE (a)-[:KNOWS]->(c)
CREATE (b)-[:KNOWS]->(c)
CREATE (c)-[:KNOWS]->(d)
But calling a POST query with the following query will return 2 results.data, each of them with a "graph", consisting of 2 nodes and a links?
{"statements":[
{
"statement":"MATCH (p:Person {name:{pName}})-[l:KNOWS]-(q:Person) RETURN p,l,q",
"parameters":{"pName":"a"},
"resultDataContents":["graph"]
}
]}
Is there a way to return the one subgraph, without the need to reassemble the results?
Thanks for the help,
Alex
I think the issue is that the same person will be returned twice by your query. Change the return statement to:
RETURN collect(distinct(p)),collect(l),collect(distinct(q))
That will give you the following response:
{
"results": [
{
"columns": [
"collect(distinct(p))",
"collect(l)",
"collect(distinct(q))"
],
"data": [
{
"graph": {
"nodes": [
{
"id": "1849644",
"labels": [
"Person"
],
"properties": {
"name": "b"
}
},
{
"id": "1849645",
"labels": [
"Person"
],
"properties": {
"name": "c"
}
},
{
"id": "1849643",
"labels": [
"Person"
],
"properties": {
"name": "a"
}
}
],
"relationships": [
{
"id": "4052753",
"type": "KNOWS",
"startNode": "1849643",
"endNode": "1849644",
"properties": {}
},
{
"id": "4052754",
"type": "KNOWS",
"startNode": "1849643",
"endNode": "1849645",
"properties": {}
}
]
}
}
]
}
],
"errors": []
}
Whilst working on something similar (https://stackoverflow.com/questions/26067792/neo4j-cypher-gui) I've run into the same problem. The documentation: http://docs.neo4j.org/chunked/stable/rest-api-transactional.html is very light on the subject

Resources