How to get node's id with cypher request? - neo4j

I'm using neo4j and making executing this query:
MATCH (n:Person) RETURN n.name LIMIT 5
I'm getting the names but i need the ids too.
Please help!

Since ID isn't a property, it's returned using the ID function.
MATCH (n:Person) RETURN ID(n) LIMIT 5

Not sure how helpful or relevant this is, but when I'm using the NodeJS API the record objects returned from Cypher queries have an identity field on the same level as the properties object (e.g record.get(0).properties, record.get(0).identity). I'm assuming you aren't just doing plain Cypher queries and actually using a driver to send the queries - so you might not have to run another MATCH statement.
I'm aware that the OP is asking about Cypher specifically - but it might be helpful to other users that stumble upon this question.

Or you can take a look on the Neo4j Cypher Refcard
You can get a short look to a lots of functions and patterns you can write.
And more about functions on The Neo4j Developer Manual - Chapter 3. Cypher - 3.4. Functions

Related

Is size() still faster than EXISTS in neo4j?

I found this guide on query tuning for Neo4j 2.2, and one of the tips in the guide is that when finding whether a relationship exists, this query:
size((n)-[:DIRECTED]->()) <> 0
is faster than this query:
EXISTS((n)-[:DIRECTED]->())
To me, it seems counter-intuitive that finding the total number of relationships is faster than determining whether the relationship exists at all. My question is- has EXISTS been optimized in later versions of Neo4j so that this tip is no longer necessary? And if not, what is the difference between these two functions that enables size() to be so much faster?
The Cypher query planners undergo continuous improvement, and the cited performance difference (that existed in neo4j 2.2) no longer exists.
For example, using PROFILE in neo4j 3.4.1, these 2 queries now produce essentially the same efficient execution plan (using the degree count):
PROFILE
MATCH (n:Person) WHERE SIZE((n)-[:DIRECTED]->()) > 0
RETURN count(*);
PROFILE
MATCH (n:Person) WHERE EXISTS((n)-[:DIRECTED]->())
RETURN count(*);

Weird results from cypher collaborative filter query

I am using one of the neo4j practice graphs (see below) to learn cypher
and running a query to search for people who both acted int and directed a movie, I'm running the following commands:
:play movie graph
MATCH (p:Person)-[a:ACTED_IN]->(m:Movie)<-[d:DIRECTED]-(p)
RETURN p,m,a,d,type(a),type(d)
I few things don't make sense:
for some rows in the result type(a) is not ACTED_IN but
PRODUCER or WROTE etc.
a lot of nodes are returned which don't seem to satisfy this pattern
using OPTIONAL MATCH works exactly right but I don't know why?
Any help would be much appreciated
As cybersam commented, this definitely looks like a bug in the compiled runtime.
If you PROFILE this you can see it's using compiled runtime; if you prefix the query with CYPHER runtime=slotted we get expected results.
I'll pass this along to the cypher team.

Neo4j - is it possible to visualise a simple overview of my database?

I've got my graph database, populated with nodes, relationships, properties etc. I'd like to see an overview of how the whole database is connected, each relationship to each node, properties of a node etc.
I don't mean view each individual node, but rather something like an ERD from a relational database, something like this, with the node labels. Is this possible?
You can use the metadata by running the command call db.schema().
In Neo4j v4 call db.schema() is deprecated, you can now use call db.schema.visualization()
As far as I know, there is no straight-forward way to get a nicely pictured diagram of a neo4j database structure.
There is a pre-defined query in the neo4j browser which finds all node types and their relationships. However, it traverses the complete graph and may fail due to memory errors if you have to much data.
Also, there is neoprofiler. It's a tool which claims to so what you ask. I never tried and it didn't get too many updates lately. Still worth a try: https://github.com/moxious/neoprofiler
Even though this is not a graphical representation, this query will give you an idea on what type of nodes are connected to other nodes with what type of relationship.
MATCH (n)
OPTIONAL MATCH (n)-[r]->(x)
WITH DISTINCT {l1: labels(n), r: type(r), l2: labels(x)}
AS `first degree connection`
RETURN `first degree connection`;
You could use this query to then unwind the labels to write that next cypher query dynamically (via a scripting language and using the REST API) and then paste that query back into the neo4j browser to get an example set of the data.
But this should be good enough to get an overview of your graph. Expand from here.

Sorting a collection in Cypher and ordering results in the same order as the collection

I'm new to Cypher and I'm trying the following. I have a graph where the relationships have a numeric property. I want to write a query like:
start n=node(*)
match n-[r *1..3]->m
return n,m, r
order by r.myproperty
This doesn't work since r in this case is a collection.
This is hard to do at the moment. I've been wanting to implement some functionality to handle it--my idea is here:
https://github.com/neo4j/neo4j/issues/30
Please comment on the issue if you'd like to see it happen.

efficiency of where clause in cypher vs match

I'm trying to find 10 posts that were not LIKED by user "mike" using cypher. Will putting a where clause with a NOT relationship be efficient than matching with an optional relationship then checking if that relationship is null in the where clause? Specifically I want to make sure it won't do the equivalent of a full table scan and make sure that this is a scalable query.
Here's what I'm using
START user=node:node_auto_index(uname:"mike"),
posts=node:node_auto_index("postId:*")
WHERE not (user-[:LIKES]->posts)
RETURN posts SKIP 20 LIMIT 10;
Or can I do something where I filter on a MATCH optional relationship
START user=node:node_auto_index(uname="mike"),
posts=node:node_auto_index("postId:*")
MATCH user-[r?:LIKES]->posts
WHERE r IS NULL
RETURN posts SKIP 100 LIMIT 10;
Some quick tests on the console seem to show faster performance in the 2nd approach. Am I right to assume the 2nd query is faster? And, if so why?
i think in the first query the engine runs through all postID nodes and manually checks the condition of not (user-[:LIKES]->posts) for each post ID
whereas in the second example (assuming you use at least v1.9.02) the engine picks up only the post nodes, which actually aren't connected to the user. this is just optimalization where the engine does not go through all postIDs nodes.
if possible, always use the MATCH clause in your queries instead of WHERE, and try to omit the asterix in the declaration START n=node:index('name:*')

Resources