How to query Neo4j nodes and the relationship between the nodes? - neo4j

Now I have a graph like this:
Then I want to query the nodes which the "SGJ" "HAVE"
MATCH (n:User) -[R:MASTER]-> (k:KNode)
WHERE n.username={username}
RETURN k
But I get the result like this:
{
"id": 360,
"children": null,
"name": "Arrays",
"intro": "this is an intro"
},
{
"id": 300,
"children": null,
"name": "Java",
"intro": "this is an intro"
}
The relationship between these nodes just gone, I hope I can query the nodes with the relationship remain like:
{
"id": 360,
"children": [
{
"id": 300,
"children": null,
"name": "Java",
"intro": "this is an intro"
}
],
"name": "Arrays",
"intro": "this is an intro"
}
Here's the entity definition:
#Data
#NodeEntity
public class KNode {
#GraphId
Long id;
#Relationship(type = "BELONGS_TO", direction = Relationship.INCOMING)
List<KNode> children;
private String name;
private String intro;
}
Is there any solution? Thanks.

You are just returning a node instead of path. Try one of these requests to return also the children and relationship :
MATCH (n:User) -[R:MASTER]-> (k:KNode)
WHERE n.username={username}
OPIONAL MATCH p=(k)-[r]-(c)
RETURN p
Or :
MATCH (n:User) -[R:MASTER]-> (k:KNode)
WHERE n.username={username}
WITH k
MATCH p=(k)-[r]-(c)
RETURN p

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;

Return nodes together with relations

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

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 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/cypher: Return id as property

I've got this super simple cypher query for my juicy graph database of two nodes:
MATCH (n) RETURN n
And it's returning the two nodes as such:
{
"results": [
{
"columns": [
"n"
],
"data": [
{
"row": [
{
"name": "node 1",
"description": "This is my first node."
}
]
},
{
"row": [
{
"name": "node 2",
"description": "This is my second node."
}
]
}
]
}
],
"errors": []
}
I was kind of expecting to get the id out as a property with "name" and "description". How can i get it in there? I know I can go something like:
MATCH (n) RETURN n, id(n)
But that would put the id outside the object and I don't want that.
You can use map {foobar:42}and collection structures in Cypher [1,2,3]
so you can return:
RETURN {id:id(n), labels: labels(n), data: n}
or you can use
{"statement":"match (n) return n","resultDataContents":["graph"]}
as additional parameter to your POST request.

Resources