neo4j query error "dont know how to compare" - neo4j

I loaded Neo4j with Pizza.owl file using hermit reasoner and Java.
when i pass a simple query:
match (n) where n="name:Pizza" return n;
am getting the following error
Don't know how to compare that. Left: Node[1]{name:"owl:Thing"} (NodeProxy); Right: "name:Pizza" (String)
Is NodeProxy a datatype? How can I make both of them to be compared. Can I do casting while querying? Any query to change datatype of the entire graph nodes? How to check the type of the node?

You are comparing a node n to a string "name:Pizza", which doesn't make sense. What you want is to compare the property name of node n with the string "Pizza": WHERE n.name = "Pizza". The whole query then looks like this
MATCH (n)
WHERE n.name = "Pizza"
RETURN n
Nodes don't really have types. Take a look at the Neo4j manual to more about nodes, relationships, properties and labels and about Cypher in general, and the WHERE clause in particular.

Related

What is difference between ANY and IN clause in Neo4j?

Neo4j has two different clauses to find value in an array, ANY and IN. Please explain, how they are different as both are used to filter the data by checking if, the specified value is present in the array or not.
Query#1 : MATCH (n) WHERE any(color IN n.liked_colors WHERE color = 'yellow') RETURN n
Result#1: Node with name Eskil
Query#2 : Match (n) where 'yellow' in n.liked_colors return n
Result#2: Node with name Eskil
If both query return same results then where is the diffrence.
In your simple example case the results are the same.
However any() allows more complex means of filtering, especially when we aren't using this to simply detect membership of a known value in a list:
MATCH (n:Person)
WHERE any(color in n.liked_colors WHERE (n)<-[:KNOWS|MARRIED*]-(other:Person {eyes:color}))
Find a person where for any of their liked colors, we can traverse the given pattern to find another person with eyes of that color.

Neo4j count Query

match(m:master_node:Application)-[r]-(k:master_node:Server)-[r1]-(n:master_node)
where (m.name contains '' and (n:master_node:DeploymentUnit or n:master_node:Schema))
return distinct m.name,n.name
Hi,I am trying to get total number of records for the above query.How I change the query using count function to get the record count directly.
Thanks in advance
The following query uses the aggregating funtion COUNT. Distinct pairs of m.name, n.name values are used as the "grouping keys".
MATCH (m:master_node:Application)--(:master_node:Server)--(n:master_node)
WHERE EXISTS(m.name) AND (n:DeploymentUnit OR n:Schema)
RETURN m.name, n.name, COUNT(*) AS cnt
I assume that m.name contains '' in your query was an attempt to test for the existence of m.name. This query uses the EXISTS() function to test that more efficiently.
[UPDATE]
To determine the number of distinct n and m pairs in the DB (instead of the number of times each pair appears in the DB):
MATCH (m:master_node:Application)--(:master_node:Server)--(n:master_node)
WHERE EXISTS(m.name) AND (n:DeploymentUnit OR n:Schema)
WITH DISTINCT m.name AS n1, n.name AS n2
RETURN COUNT(*) AS cnt
Some things to consider for speeding up the query even further:
Remove unnecessary label tests from the MATCH pattern. For example, can we omit the master_node label test from any nodes? In fact, can we omit all label testing for any nodes without affecting the validity of the result? (You will likely need a label on at least one node, though, to avoid scanning all nodes when kicking off the query.)
Can you add a direction to each relationship (to avoid having to traverse relationships in both directions)?
Specify the relationship types in the MATCH pattern. This will filter out unwanted paths earlier. Once you do so, you may also be able to remove some node labels from the pattern as long as you can still get the same result.
Use the PROFILE clause to evaluate the number of DB hits needed by different Cypher queries.
You can find examples of how to use count in the Neo4j docs here
In your case the first example where:
count(*)
Is used to return a count of each returned item should work.

How to show relationships in an optional manner in neo4j?

I have multiple nodes and relationships in neo4j, certain nodes have relationship depth as 4, while certain have 2. I'm using neo4j's HTTP API to get the data in graph format
Sample query:
MATCH p= (n:datasource{resource_key:'ABCD'})-[:is_dataset_of]-(c:dataset)-[q]-(v:dataset_columns)-[s]-(b:component)-[w]-(e:dashboard) return p
If i use this query then i can get output if this exact relationship is present but I also want to get the output if the 2nd relationship is not available, Any pointers on how to achieve this?
Here is one way:
MATCH p = (:person1 {hobby: 'gamer'})-[:knows]-(:person2)
RETURN p
UNION ALL
MATCH p = (:person1 {hobby: 'gamer'})-[:knows]-(:person2)--(:person3)
RETURN p
The UNION clause combines the results of 2 queries. And the ALL option tells UNION to not bother to remove duplicate results (since the 2 subqueries will never produce the same paths).
If you really want the path to be returned, you can do something along these lines, using apoc (https://neo4j-contrib.github.io/neo4j-apoc-procedures/3.4/nodes-relationships/path-functions/)
MATCH requiredPath=(n)-[r]->(m)
OPTIONAL MATCH optionalPath = (m)-[q]->(s)
RETURN apoc.path.combine(requiredPath,optionalPath) AS p

Neo4j indices slow when querying across 2 labels

I've got a graph where each node has label either A or B, and an index on the id property for each label:
CREATE INDEX ON :A(id);
CREATE INDEX ON :B(id);
In this graph, I want to find the node(s) with id "42", but I don't know a-priori the label. To do this I am executing the following query:
MATCH (n {id:"42"}) WHERE (n:A OR n:B) RETURN n;
But this query takes 6 seconds to complete. However, doing either of:
MATCH (n:A {id:"42"}) RETURN n;
MATCH (n:B {id:"42"}) RETURN n;
Takes only ~10ms.
Am I not formulating my query correctly? What is the right way to formulate it so that it takes advantage of the installed indices?
Here is one way to use both indices. result will be a collection of matching nodes.
OPTIONAL MATCH (a:B {id:"42"})
OPTIONAL MATCH (b:A {id:"42"})
RETURN
(CASE WHEN a IS NULL THEN [] ELSE [a] END) +
(CASE WHEN b IS NULL THEN [] ELSE [b] END)
AS result;
You should use PROFILE to verify that the execution plan for your neo4j environment uses the NodeIndexSeek operation for both OPTIONAL MATCH clauses. If not, you can use the USING INDEX clause to give a hint to Cypher.
You should use UNION to make sure that both indexes are used. In your question you almost had the answer.
MATCH (n:A {id:"42"}) RETURN n
UNION
MATCH (n:B {id:"42"}) RETURN n
;
This will work. To check your query use profile or explain before your query statement to check if the indexes are used .
Indexes are formed and and used via a node label and property, and to use them you need to form your query the same way. That means queries w/out a label will scan all nodes with the results you got.

How to get nodes with unique properties in neo4j?

In Dr.who dataset that is available in neo4j, I want to get all the nodes having properties character. The cypher query I am using is :-
START n=node(*)
WHERE
HAS(n.property)
RETURN n
But this query, even returns me some nodes which has character and other property keys too (as shown in http://imgur.com/ujizTZj) but I want to get nodes having only character property key only.
If you use Neo4j 2.2+, forget the "START" clause and use the "MATCH" instead.
Also, for your use case I don't think before 2.2 it is possible, but in 2.2+ you can do :
MATCH (n)
WHERE HAS(n.character)
AND size(keys(n)) = 1
RETURN n

Resources