Identifying parameters of Cypher query - neo4j

Is there an API for identifying the named parameters of a given Cypher query? When taking the following query as example:
MATCH (n) WHERE n.firstName = { name } AND n.LastName = { lastName } RETURN n
Then this API should return "name" and "lastName".
Does Neo4j provide such an API or would I have to manually parse the query string to identify any parameters it contains?

There is no API for obtaining the names of the properties used in a Cypher query. There is generally no need for such a utility, since the code making the query should already know that information.

Maybe you can begin your query with parameters in a transaction, get the result/errors and rollback it ?
http://docs.neo4j.org/chunked/stable/rest-api-transactional.html

Related

Can we make cypher field query Case-Insensitive

It may seem duplicate of this but it is not. Can we make cypher query case insensitive based on fields. I know we can use regex for values but we need it based on fields.
e.g.
MATCH (c:customer) WHERE c.CUSTOMERNUMBER = '1088' RETURN c
Above query returns a result, but following does not
MATCH (c:Customer) WHERE c.CustomerNumber = '1088' RETURN c
Here lable Customer and property CustomerNumber are having different cases.
You can use PROPERTIES to get a map representation of a node, and then use KEYS so that you can iterate over them. Because "Name", "NAME", and "Prop1" are all equally unique property names, and they can all or none exist, as far as the DB is concerned. You will have to iterate every property of the node to find a field that matches your criteria.
MATCH (n)
WHERE ANY(key in KEYS(n) WHERE lower(key)="name" AND n[key]="Neo")
RETURN n
This is more flexible than simple case insensitivity, but it is also expensive.

can you do an optional match if a parameter exists in neo4j cypher?

When users are authenticated, I want to extend my cypher query to include whether a user has a :LIKED relationship to an item node, and include this in my projection as a boolean value.
if the user is authenticated I will supply a {userId}, alternatively the {userId} param will be null. I've investigated WHERE, and exists but this doesn't seem like the right approach.
Is this possible in cypher at all currently?
EDIT:
This seems to be possible using the OPTIONAL MATCH in my first tests, but is this the correct approach?
MATCH (m:Media {mediaId: {itemId}})
WITH m, labels(m) as labels
OPTIONAL MATCH (m)<-[r:LIKED]-(:Person {userId: {userId}})
RETURN m { .*, labels, liked: exists(properties(r).createdAt) } AS result
LIMIT 1
Lastly, I may have several relationships, that could only be present if the user making the request is authenticated, and the userId param is nit NULL.
any suggestions or improvements would be fantastic from more experienced cypher users.
[EDITED]
If you do not need to test for the existence of the createdAt property, then this even simpler query would work:
MATCH (m:Media {mediaId: $itemId})
RETURN m { .*, labels:labels(m),
liked: EXISTS((m)<-[:LIKED]-(:Person {userId: $userId})) } AS result;

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.

How to query for properties with dashes in Neo4j using Cypher

I am trying to query for properties in Neo4j using the Cypher Query API. The query I am attempting is as follows:
String query = "start n=node(*) where (n.property-id = 'someid') return ID(n)"
I get an error when executing as follows:
Exception in thread "main" Unknown identifier id.
So, this means that Neo4j is treating the dash in property-id as a keyword. How does one go about formulating queries with dashes in a node/relationship property?
Thank you.
Escape the property with backticks:
String query = "start n=node(*) where (n.`property-id` = 'someid') return ID(n)"

Wildcard search with cypher query and spring neo4j

When I execute the below query in neo4j console, i get the correct result set.
start n=node:search('username:*') return n.username;
I am using spring data neo4j in my java web app.
In the repository code, i defined query as:
#Query("START n=node:search({0}) RETURN n.name as name, n.username as username
Parameter passed
{0} = 'username:*'
There is no exception but the result set size is 0.
Can you please help me resolve the issue?
Unfortunately, the whole lucene query cannot be a parameter in Cypher, as far as I know. You'll need to resort to string concatenation/interpolation, probably. Similar to the issue I posted about relationship types as parameters: https://github.com/neo4j/neo4j/issues/340

Resources