neo4JClient returning empty nodes - neo4jclient

I am using neo4JClient to query a list of nodes in the graph and present them on the web browser as a table. In order to get data, the following code is used.
var query = client
.Cypher
.Match("DataSpace")
.Return(DataSpace => DataSpace.As<DataSpace>());
var longBooks = query.Results;
jsonString = JsonConvert.SerializeObject(longBooks, Formatting.None, settings);
context.Response.Write(jsonString);
The graph contains various other nodes.
The Resultset at the Browser Window is :
[{"DataSpaceName":"DS1","DataSpaceDescription":"First Dataspace"},{"DataSpaceName":"DS2","DataSpaceDescription":"Second Dataspace"},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{}]
There are empty nodes that get returned, which I think correlates to the other nodes in the graph.
Can I get rid of the Empty Nodes ?

The query returns all nodes because that's what you asked for. Your Neo4jClient query simply translates to this Cypher query:
MATCH DataSpace
RETURN DataSpace
In this case DataSpace is simply an identifier that represents every node, without additional constraints.
Do your DataSpace nodes have anything that separates them from other nodes, e.g. a label, a common node that they're all connected to, a unique property?
In case the nodes have a unique DataSpace label, you can for query them with:
var query = client
.Cypher
.Match("ds:DataSpace")
.Return(ds => ds.As<DataSpace>());
In case DataSpaceName is a property that is only present on DataSpace nodes, you can try:
var query = client
.Cypher
.Match("ds")
.Where("has(ds.DataSpaceName)")
.Return(ds => ds.As<DataSpace>());

Related

Unwind array and match with other nodes using Cypher on Neo4j graph database

I'm creating an app using GRANDstack on top of a Neo4j graph database and I'm struggling with writing a query that unwinds a property array, matches some IDs, pullsback names associated with the IDs and repackages them into a new array.
Essentially, I have Memory nodes (Mems) and Person nodes (Person) and their relationship is as follows: (Mems)-[WITH]->(Person). i.e. you can have a memory of something where you were WITH multiple people. The Mems nodes contain a personID property that is an array of IDs and the relationship in the graph database is built from the array of personIDs in Mems nodes that match the personIDs in the Person nodes.
The result I'm trying to achieve is like the below, however I haven't found a way to return the nicknames from the Person nodes:
The query I'm using to generate the above is below:
MATCH (m:Mem)-[WITH]->(p:Person)
WHERE m.personID IS NOT NULL
UNWIND m.personID as personID
CALL {
WITH personID
MATCH (p:Person)
WHERE personID = p.personID
RETURN p.nickname
}
RETURN m.mem, m.date, personID, p.nickname
I think it's close to what I need but I just can't figure out the last bit where I can return the nicknames associated with the personIDs. This might be something that APOC is more capable of doing?
[UPDATED]
This should work for you:
MATCH (m:Mem)-[:WITH]->(p:Person)
WHERE p.personID IN m.personID
RETURN m.mem, m.date, p.personID, p.nickname
Also, notice that the relationship pattern must use:WITH instead of WITH if you want to query for the WITH relationship type.
Addendum
Of course, since you have the WITH relationships, you should consider deleting the redundant m.personID property. You should get the same results without m.personID this way:
MATCH (m:Mem)-[:WITH]->(p:Person)
RETURN m.mem, m.date, p.personID, p.nickname

Is there any Cypher Query for to return all the properties of a node but excluding a particular property?

Retrieving all the properties of a particular node in Neo4j is a used to one among many queries. But How can I retrieve the properties of a node excluding a particular property, the labels, and the ID ?
If this below query is executed by java program after successful connection:
MATCH (n: `Group_A`: `Topper`) RETURN n
Now, Then the output it prints in screen is:
{"id":4, "labels":["Group_A", "Topper"], "name":"tom", "shift":"morning", "salary":"5000", "blood_group":"AB", "specialisation":"C#"}
I am expecting all the property of the node (n: Group_A: Topper), excluding the property type and its value, the id and the labels associated with the node.
Hence, the desired output in screen will look like:
{"name":"tom", "shift":"morning", "blood_group":"AB", "specialisation":"C#"}
========================================================================
[N.B. - I am working with Neo4j jar file where I am firing query of Neo4j and getting the result using println() method. I have my Neo4j running in the background. All are working fine with the successful connection of Neo4j but I am insearch of the Neo4j query.]
[UPDATED]
To avoid getting node metadata (in your client results), you should not return a node directly. Instead, you can use the PROPERTIES() function to get just the properties in a map:
MATCH (n: `Group_A`: `Topper`)
RETURN PROPERTIES(n) AS props
But if you also want to avoid returning some of the properties (e.g. "salary") as well, you can use the apoc.map.removeKey() function to remove them. Since that function returns a map instead of a node, it will also not contain any metadata (so you would not need to use the PROPERTIES() function in this case). For example:
MATCH (n: `Group_A`: `Topper`)
RETURN apoc.map.removeKey(n, 'salary') AS props
You could use map projection.
All node properties (no metadata)
MATCH (n: `Group_A`: `Topper`)
RETURN n {.*}
Specific properties
MATCH (n: `Group_A`: `Topper`)
RETURN n {.prop1, .prop2}

Visualize connected components in Neo4j

I can find the highest densely connected component in the graph using the code below:
CALL algo.unionFind.stream('', ':pnHours', {})
YIELD nodeId,setId
// groupBy setId, storing all node ids of the same set id into a list
MATCH (node) where id(node) = nodeId
WITH setId, collect(node) as nodes
// order by the size of nodes list descending
ORDER BY size(nodes) DESC
LIMIT 1 // limiting to 3
RETURN nodes;
But it does not help me visualize the topmost densely connected component (sub-graph) because the output graph it emits are disjoint nodes. Is it possible to visualize the densely connected component. If yes, then how
I tried this query but I am getting different the result.
I haven't used these algorithms and I don't know much about it, but I think you added an extra character (colon) in the query.
Can you check with pnHours instead of :pnHours.
I remove colon(:) from the query and I am getting the proper result (also I am able to get the relationships as well because Neo4j browser fetches it although it's not specified in the query).
If you still don't get check the following query:
CALL algo.unionFind.stream('', 'pnHours', {})
YIELD nodeId,setId
// groupBy setId, storing all node ids of the same set id into a list
MATCH (node) where id(node) = nodeId
WITH setId, collect(node) as nodes
// order by the size of nodes list descending
ORDER BY size(nodes) DESC
LIMIT 1 // limiting to 3
WITH nodes
UNWIND nodes AS node
MATCH (node)-[r:pnHours]-()
RETURN node,r;
If you want to visualize then in Neo4j browser then use:
CALL algo.unionFind.stream('', ':pnHours', {})
YIELD nodeId,setId
// groupBy setId, storing all node ids of the same set id into a list
MATCH p=(node)-->() where id(node) = nodeId
WITH setId, collect(p) as paths
// order by the size of nodes list descending
ORDER BY size(paths) DESC
LIMIT 1 // limiting to 3
// Maybe you need to unwind paths to be able to visualize in Neo4j browser
RETURN paths;
It is not the most optimized query but should do just fine on small datasets.
The following query should return all the single-step paths in the largest pnHours-connected component (i.e., the one having the most nodes). It only gets the paths for the largest component.
CALL algo.unionFind.stream(null, 'pnHours', {}) YIELD nodeId, setId
WITH setId, COLLECT(nodeId) as nodeIds
ORDER BY SIZE(nodeIds) DESC
LIMIT 1
UNWIND nodeIds AS nodeId
MATCH path = (n)-[:pnHours]->()
WHERE ID(n) = nodeId
RETURN path
The neo4j browser's Graph visualization of the results will show all the nodes in the component and their relationships.

Why don't some query results have graph representation in Neo4j?

In the Neo4j Browser, I performed one query as follows:
match (subject:User {name:{name}})
match (subject)-[:works_for]->(company:Company)<-[:works_for]-(person:User),
(subject)-[:interested_in]->(interest)<-[:interested_in]-(person)
return person.name as name, count(interest) as score,
collect(interest.name) as interests order by score DESC
The result only has the "table" and "text" views, without the "graph". Normally, a query can generate a subgraph. Right?
If you look at your return, you're not returning any actual nodes or relationships. You're returning property values (strings), counts (longs), and collections of strings. If you returned person instead you would probably be able to see a graphical result, as the return would include data (id, labels, properties) that could be used to display graph elements.

Neo4j server plugin basic questions

I am using Neo4J v2.1.5 and creating a server plugin.
How to create a unique node i.e. guarantee uniqueness of a property?
Is there a hook where in the plugin lifecycle, constraints and indexes can be created?
Returning a node returns the complete database. How can I return just a node or a pojo list as JSON? Are there any working examples or explanation of Representation available?
I am using Java API and not Cypher.
How to create a unique node i.e. guarantee uniqueness of a property?
You can create a unique constraint on a (label, property) pair which will ensure the uniqueness of that property.
e.g.
CREATE UNIQUE CONSTRAINT ON :Person(name)
Would ensure you can't have two people nodes with the same name. If you want to do that from the Java API you'd do something like this:
try ( Transaction tx = graphdb.beginTx() )
{
graphdb.schema()
.constraintFor( DynamicLabel.label( "Person" ) )
.assertPropertyIsUnique( "name" )
.create();
tx.success();
}
Is there a hook where in the plugin lifecycle, constraints and indexes can be created?
You can do that in a transaction but IIRC you can only create one index/constraint per transaction.
Returning a node returns the complete database. How can I return just a node or a pojo list? Are there
any working examples or explanation of Representation available?
Do you mean from cypher? A simple query which will only return one node would be this:
MATCH (n)
RETURN n
LIMIT 1
In cypher land that will return you a map of the properties that the node has on it. If you want to get something more specific you could try this:
MATCH (n:Person)
RETURN n.name AS personName
LIMIT 1
So then you'd get a String back for that column in the result set.
-- Updating for Java API --
From the Java API you can write your own traversals which will give you back 'Node' and 'Relationship' objects. From those you'd then have to extract any properties that you're interested in.
try ( Transaction tx = graphDatabaseService.beginTx() )
{
ResourceIterable<Node> people = GlobalGraphOperations.at( graphDatabaseService ).getAllNodesWithLabel( DynamicLabel.label( "Person" ) );
for ( Node node : people )
{
String name = (String) node.getProperty( "name" );
}
tx.success();
}
Hi with cypher i can sugesst you few thing,
Q How to create a unique node i.e. guarantee uniqueness of a property?
Ans.
first chosse a property that could be unique for that node , same like Primary key in of your relational database system,
i.e Id
now you merge to create a node,
MERGE (u:User { Id:1 })
set u.Name='Charlie'
RETURN u
if the user with Id will not exist it will create it,
then using set Clause you can set other property or hole obejct as well,
Q Returning a node returns the complete database. How can I return just a node or a pojo list as JSON? Are there any working examples or explanation of Representation available?
Ans. Same way to match if you pass the unique id and try to search it will return you only that particualr node only i.e
match(u:User { Id:1 }) return u
to create such Id , i will suggest you to go with GUID created in programing lunguaze like C#,
but with neo4j 3.x you also used autoincremented propery as well.

Resources