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
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
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
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
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.
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?