apoc.periodic.commit doesn't result in updates - neo4j

The following query results in 10 updated nodes:
MATCH (a:ns3__Organization)-[r:ns4__isDomiciledIn]->(b:Resource)
WITH a,b LIMIT 10
SET a.isDomiciledIn = b.Country
I'm trying to apply it to my whole graph with apoc.periodic.commit through the following query:
CALL apoc.periodic.commit("
MATCH (a:ns3__Organization)-[r:ns4__isDomiciledIn]->(b:Resource)
WITH a,b LIMIT $limit
SET a.isDomiciledIn = b.Country
", { limit : 50000});
Somehow it results in 0 update. What am I doing wrong?
Thanks for your help.

You should try this one :
CALL apoc.periodic.commit("
MATCH (a:ns3__Organization)-[r:ns4__isDomiciledIn]->(b:Resource)
WHERE NOT a.isDomiciledIn = b.Country
WITH a,b LIMIT $limit
SET a.isDomiciledIn = b.Country
RETURN count(*)
", { limit : 50000});
You errors :
no count(*) at the end of your query. SO your query never ends
no WHERE clause to filter the result to only nodes that are not yet updated

Related

Boolean value return from Neo4j cypher query

I have this query for returning the hashTag name, hashTag count and if it has the Featured label return true. HashTag node just has a tag property`. It's working :
MATCH (:RateableEntity)<-[:TAG]-(hashtag:HashTag:Featured)
WITH hashtag,
(CASE WHEN 'Featured' IN LABELS(hashtag) THEN true ELSE false END) AS HASHTAG_FEATURED_LABEL
RETURN hashtag.tag As HASHTAG_NAME,
COUNT(hashtag) as HASHTAG_FREQUENTLY,
HASHTAG_FEATURED_LABEL
ORDER BY HASHTAG_NAME ASC
SKIP 0
LIMIT 20
But I'm searching for a better way without Case.
Does anyone have any idea?
Thanks
You can just return the expression, no need for the CASE here :
MATCH (:RateableEntity)<-[:TAG]-(hashtag:HashTag:Featured)
WITH hashtag,
'Featured' IN LABELS(hashtag) AS HASHTAG_FEATURED_LABEL
RETURN hashtag.tag As HASHTAG_NAME,
COUNT(hashtag) as HASHTAG_FREQUENTLY,
HASHTAG_FEATURED_LABEL
ORDER BY HASHTAG_NAME ASC
SKIP 0
LIMIT 20

Get count of multiple nodes with no relations in cypher query

How to get the count of more than one nodes.
MATCH (n1:node1)
MATCH (n2:node2)
MATCH (n3:node3) where n3.status = "active"
return count(n1) as countOfNode1,
count(n2) as countOfNode2,
count(n3) as countOfNode3
This query is returning duplicated result as
countOfNode1 = 0
countOfNode2 = 0
countOfNode3 = 0
where the real count is
countOfNode1 = 0
countOfNode2 = 3
countOfNode3 = 1
How to do this?
Using 'distinct' also does not solve the problem.
Given as:
return count(distinct n1) as countOfNode1,
count(distinct n2) as countOfNode2,
count(distinct n3) as countOfNode3
One possibility I'm thinking of is this
MATCH (n1:node1) WITH count(n1) as countOfNode1
MATCH (n2:node2) WITH count(n2) as countOfNode2
MATCH (n3:node3) where n3.status = "active" WITH count(n3) as countOfNode3
return countOfNode1,
countOfNode2,
countOfNode3
Or maybe
MATCH (n1:node1), (n2:node2),(n3:node3 {status:"active"} )
return count(n1) as countOfNode1,
count(n2) as countOfNode2,
count(n3) as countOfNode3

Neo4j LIMIT if parameter is set

is there a way to set a LIMIT only, if the parameter {limit} has an numeric value.
...
RETURN whatever
LIMIT {limit}
maybe in a way like this (i know, that the next code example does not work)
...
RETURN whatever
if({limit}>0)
LIMIT {limit}
thanks!
You should process this logic in your application layer by building dynamic queries.
Edit :
This can simply be done like the example below (in php but possible in all languages)
public function doMatchQuery($limit = null)
{
$query = 'MATCH (n) RETURN n';
if ($limit && $limit !== 0) {
// extend the query string
$query .= ' LIMIT '.$limit;
}
}
// Calling your function
$matchAll = $this->doMatchQuery(); // Return all n elements from the db
$matchFirstTen = $this->doMatchQuery(10); // Return the n elements with a limit of 10

Can UNION and WITH play together?

Is there any way to use the results of a UNION in another sub-query using a WITH clause?
I'm looking for something like
(
MATCH (me:Person)-[:RATES]->(r:Rating)-[:RATED_BY]->(them:Person)
WHERE me.ident = {id} AND r.date = {date}
RETURN them
UNION ALL
MATCH (me:Person)<-[:RATED_BY]-(r:Rating)<-[:RATES]-(them:Person)
WHERE me.edent = {id} AND r.date = {date}
RETURN them
)
WITH them
RETURN them.name, COUNT( them.name) as ratingCount
ORDER BY ratingCount DESC
LIMIT 10
only nothing like this is supported by cypher.
And yes, I know that in this case I should be using
MATCH (me:Person)-[:RATES|RATED_BY]-(r:Rating)-[:RATES|RATED_BY]-(them:Person)
WHERE me.ident = {id} AND r.date = {date}
RETURN them.name, COUNT( them.name) as ratingCount
ORDER BY ratingCount DESC
LIMIT 10
which is fine and dandy, but I think that I'm going to get some more complex requests down the road where this won't work.

Cypher Query, make a where by several nodes properties if they have the same type of relationship

If we have a node related with other nodes by the same type of relationship
classmetadata<-INSTANCE_OF-instance(TheNodeINeed)-RELATED_TO->...................
- ->listype(The owner(name=d,etc))
- ->listype(The state(name=x,etc))
- ->listype(The propertie(name=y,etc))
- ->listype(The location(name=z,etc))
The instance node to find, must be looking by a node classmetadata within a index by its name(this is easy) and instance name (this is easy too) and also by the listype.name=.. and listype.name=.. and listype.name=.. and here is the problem:
If I try looking just for the instance with name MyInstance who is RELATED_TO a owner with name d, here I only quering about one listype node there's no problem, this query works
START classmetadata = node:classes(name = "MyClassMetadata")
MATCH classmetadata<-[:INSTANCE_OF]-instance-[:RELATED_TO]->listype
WHERE instance.name="MyInstance" and listype.name = "d"
RETURN instance, listype
ORDER BY instance.name ASC skip 0 limit 10
but if I need to look for the instance with name MyInstance who is RELATED_TO a owner with name d and is also RELATED to state with name x and is also RELATED to propertie with name y there is a problem the query result is always empty, is there any way to filter about two o three or more nodes.properties(listype.name) at same time if they are related by the same type of relatioship?
something like this is not working
START classmetadata = node:classes(name = "MyClassMetadata")
MATCH classmetadata<-[:INSTANCE_OF]-instance-[:RELATED_TO]->listype
WHERE instance.name = "MyInstance" AND listype.name = "x"
AND listype.name = "y" AND listype.name="d" RETURN instance, listype
ORDER BY instance.name ASC skip 0 limit 10
I added the name property to each relationship in order to be sure that I am making the filtering in the right node.
START classmetadata = node:classes(name = "MyClassMetadata")
MATCH classmetadata<-[:INSTANCE_OF]-instance-[r1:RELATED_TO]->listype1,
instance-[r2:RELATED_TO]->listype2,
instance-[r3:RELATED_TO]->listype3
WHERE instance.name = "MyInstance" AND
r1.name="state" AND listype1.name = "x" AND
r2.name="property" AND listype2.name = "y" AND
r3.name="owner" AND listype3.name="d"
RETURN instance, listype
ORDER BY instance.name ASC skip 0 limit 10
So you want to find all listypes where the name property of listtype can be d or x or y (in your first code snippet)?
If so, then
START classmetadata = node:classes(name = "NodeType ")
MATCH classmetadata<-[:INSTANCE_OF]-instance-[:RELATED_TO]->listype
WHERE instance.state="good" and (not(listype.name in ["d","x","y"]))
RETURN instance, listype
ORDER BY instance.name ASC skip 0 limit 10
Your query above too would work...just refer to listtype uniformly- no need for listtype1, listtype2 etc.
START classmetadata = node:classes(name = "NodeType ")
MATCH classmetadata<-[:INSTANCE_OF]-instance-[:RELATED_TO]->listype
WHERE instance.state="good" and AND listype.name! =~ ".Po."
AND listype.name! =~ ".Me."
RETURN instance, listype
ORDER BY instance.name ASC skip 0 limit 10
Is that what you're looking for?

Resources