neo4j - cypher query how to check StoreID - neo4j

I am trying to figure out how to identify a database uniquely via a cypher query. I understand the StoreID along with the KernelStartTime kernel parameters with do this... can I access those parameters or something else via a cypher query?

The Cypher language currently only exposes the graph data, not metadata about the DB instance.
As a workaround, you may want to store uniquely identifying information in a singleton node (i.e., a node that is the only one having a special label) in each DB instance. This tactic will not work, however, if you want to use Cypher to distinguish between the DB instances in a HA cluster.

While technically I'm not sure if this is strictly a Cypher query or not, it is possible by querying the jmx interface through Cypher. Try this:
CALL dbms.queryJmx("org.neo4j:instance=*,name=Kernel") YIELD attributes
RETURN attributes.StoreId.value, attributes.KernelStartTime.value
Or this to list all jmx objects:
CALL dbms.queryJmx("org.neo4j:*")

Related

Get ID allocation through Cypher query (or bolt protocol)

In the Neo4j browser, I can do :play sysinfo or
:GET /db/manage/server/jmx/domain/org.neo4j/instance%3Dkernel%230%2Cname%3DPrimitive%20count
to get the ID allocation for nodes and relationships. Is there a way to get the same information through a Cypher query so that I can request it via the bolt protocol? I know I can write a query that searches all the nodes/relationships and returns the largest ID, but that's slow on a large db so I'd prefer something that can directly access the stored property.
Check out the docs, particularly dbms.queryJmx(). For this particular query,
CALL dbms.queryJmx('org.neo4j:instance=kernel#0,name=Primitive count')
If you want to explore what else you can grab, just pass in 'org.neo4j:*' as the query string instead. The exact structure of the results can get pretty... interesting depending on your choice of driver, so it may take some parsing work.

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.

Global indexes in Neo

In our company, we return a list of IDs to clients through a web service. The IDs are unique across the system. They invoke other web services passing the IDs. We don't always know the label of the ID we receive.
This does not perform:
MATCH(n {id:{my_id}) ...
While we have indexes on almost all label types, this query has no label and as thus does not use an index as far as I can tell.
Is it a bad idea to add a label called "GLOBAL" (or whatever) to all nodes so we can put a unique constraint on GLOBAL.id? Then the query above could be
MATCH(n: GLOBAL{id:{my_id}})...
and perform nicely.
Is there another way?
You can use Neo4j's internal ID to identify your resources, but it's not best practice, see Should we use the Neo4J internal id?
This is how to get a node using his neo4j's internal id:
START n=node({my_id}) return n
It's really faster than a MATCH clause, because here your query directly starts with one node, and doesn't have to filter a property accross a set of nodes, because it's internal id.
If you can handle the internal id limitations, it's the solution you are looking for.

Using TIMESTAMP() over the Neo4j REST API

I am working on an application where Neo4j data is being updated for multiple clients in realtime. The times on the different client machines may be different, so any timestamps need to be set by the Neo4j database itself.
What possibilities does the Neo4j REST API provide for running TIMESTAMP() locally and inserting it into a field?
I know that I can create a query like...
WITH TIMESTAMP() AS timestamp
MATCH (node)
WHERE id(node) = {id}
SET node.updatedAt = timestamp
, node.property = "new value"
RETURN node
... and use a transaction to execute it on the remote server. But is this the only solution? Are there ways to use the Node Properties URI so that the database will create the appropriate values dynamically?
Neo4j REST API is very limited in this case. As you mentioned you can use Cypher REST endpoint and set that value manually.
Another option is to writer your own Neo4j Unmanaged Extension, which will use Transaction Event API. It's similar to stored-procedures.
Here is very good article how to write that Extension by using GraphAware Framework - http://graphaware.com/neo4j/transactions/2014/07/11/neo4j-transaction-event-api.html
Also here is simple real-world example that kind of Extension - https://github.com/graphaware/neo4j-uuid

How do I find a string in an unknown neo4j database using Cypher?

TL,DR: I need a query which gives me all nodes/relationships which contain a certain value (in my case a string, so much I know), without knowing which property(key) contains the string. I am using neo4j(latest version), meteor (latest version) and the meteor neo4j driver, which is recommended on the neo4j website for meteor.
Currently I am working (as part of my bachelor thesis) on a tool to visualize the output of any Cypher query on any database, regardless of the database contents.
So far I've managed to correctly display nodes/relationships which are coming out. My problem now is to visualize (get nodes and relationships to feed into my frontend) textual queries like (taken from the neo4j movie database, which I am using for development)
MATCH (tom:Person {name:"Tom Hanks"})-[:ACTED_IN]->(m)<-[:ACTED_IN]-(coActors)
RETURN coActors.name
This kind of queries only returns an array of strings and not whole nodes or relationships. I now need some way (preferably a Cypher query) to get all nodes which contain for example the string "Audrey Tatou".
The problem I've now run into is that I didn't find a way to write a query which doesn't need something like
MATCH n
WHERE Person.name = "some name"
Since I don't know anything about the contents of the database I cannot use
WHERE propertyName = "propertyValue"
since I only know the value but not the name of the property.
The only solution here will be to get every nodes with your label and check properties and values using reflection on client side.
Using cypher, the solution would be to get all properties and their values and parse their values using a foreach loop. Maybe you can do this, but I'm really not sure, it's a recent feature but you can still give a try.
Here is what I found for the cypher solution: How can I return all properties for a node using Cypher?
So, you have query that returns array of string.
In fact - you can receive almost anything as result. Cypher is capable to return just bare strings, that are not related to anything.
Long story short - you can't vizualize this data, because of this data nature. Best you can do is to represent them as table (or similar), like Neo4j browser do this.
But, there is (probably) solution for you. Neo4j has feature called Legacy indexing. And there you can find full text indexes. Maybe this can help you.
You can just use a driver that returns nodes and rels, or if you do the queries manually add resultDataContents entry
{statements:[{statement:"MATCH ..","resultDataContents",["graph"]}]}
to your payload and you get nodes and relationships back.

Resources