Neo4j APOC remove all triggers - neo4j

I'd like to implement Cypher query and using APOC functions remove all of the existing triggers:
I'm trying the following query:
CALL apoc.trigger.list() yield name
CALL apoc.trigger.remove(name) yield name, installed
but it fails with the following error:
Neo.ClientError.Statement.SyntaxError: Query cannot conclude with CALL
(must be RETURN or an update clause) (line 1, column 37 (offset: 36))
"CALL apoc.trigger.list() yield name CALL apoc.trigger.remove(name)
yield name, installed" ^
How to properly implement this query ?

As the error says, a query cannot end with a CALL (unless the CALL is the only statement in the query). It needs either a write operation (MERGE, CREATE, SET, REMOVE, DELETE) or a return.
You can add RETURN name, installed at the end, if you want to return the values yielded by the call. Otherwise, if you really don't care about what is returned, RETURN DISTINCT true ought to do the trick.
Oh, and you may want to alias name in one of your YIELDs or the other, as you may get an error of a variable name conflict.

Related

(Neo4j 3.5) Executing query with two parts and the second one consists on a group of matches where at least one needs to be fulfilled

we are trying to run a cypher query but we are not able to get the results we want.
It is important to note that we cannot make this work with subqueries because we are using Neo4j 3.5 and in this version, they are still not available.
The problem is that we have two parts for a query, the first one will fix the variables for the second part, and the second part consists of multiple matches, and it has to get the results of the previous query and if at least one of the matches return a result for a row, this row is not filtered out, else if none return result it is discarded.
More specifically, the query we are trying to run is similar to the following one:
//First part of the query where we want to fix variables with the match and where
MATCH (u:User)-[:ASSIGNED_TO]->(t:Task)-[:PENDING]->(ob:Object)<-[:HAS_OPEN_OBJECT]-(do:DataObject)<-[:ASOCIATED]-(:Module)-[:CAN_LIST]->(view:WidgetObject)
WHERE u.uid = 'user_uid'
AND view.uid = 'view_uid'
AND view.object_name = do.object_type
with do, t, ob
// In this second part of the query we want to maintain the variables of the previous part and if at least one matches the value should be returned
// we have tried with UNION but we will need pagination, but even with union it's not working
MATCH (ac:Action)<-[:ASOCIATED]-(t)-[rel:COMPLETED|PENDING]->(ob)<-[:HAS_OPEN_OBJECT|HAS_CLOSED_OBJECT]-(do)
WHERE ac.name CONTAINS 'body'
WITH COLLECT({data_object_uid: do.uid}) as act_filter
MATCH (c:Comment)<-[:COMMENTED]-(t)-[rel:COMPLETED|PENDING]->(ob)<-[:HAS_OPEN_OBJECT|HAS_CLOSED_OBJECT]-(do)
WHERE c.body CONTAINS 'body'
WITH act_filter + COLLECT({data_object_uid: do.uid}) as comment_filter
MATCH (at:Attachment)<-[:HAS_ATTACHMENT]-(t)-[rel:COMPLETED|PENDING]->(ob)<-[:HAS_OPEN_OBJECT|HAS_CLOSED_OBJECT]-(do)
WHERE at.name CONTAINS 'body'
WITH comment_filter + COLLECT({data_object_uid: do.uid}) as attachment_filter
UNWIND attachment_filter as row
return row.data_object_uid
We are not sure if in the second part, the second and third matches are maintaining the same subset of results coming from the first part of the query.
A funny behavior we have found is that if we remove the last match we are getting results but if we add it, we are not getting any results. We do not understand this behavior because if the second match is returning results and they are stored in a variable after a collect, appending this to the next collected results should return something.
For example, if the second match returns as comment_filter [{data_object_uid: "343dienmd3-dasd"}] and the third match is not returning anything, after the concatenation in the WITH clause it should return the same thing, but the result is empty.
We need some light here, we don't know if we are close and we are making a stupid mistake or we are getting all wrong and we need to change the approach completely.
Since you do not know which of the three matches in the second part will yield results, I would try something along the lines below:
NOTE I used ASSOCIATED instead of ASOCIATED
MATCH (n)<-[:ASSOCIATED|COMMENTED|HAS_ATTACHMENT]-(t)-[rel:COMPLETED|PENDING]->(ob)<-[:HAS_OPEN_OBJECT|HAS_CLOSED_OBJECT]-(do)
WHERE
(n:Action AND n.name CONTAINS 'body')
OR
(n:Comment AND n.body CONTAINS 'body')
OR
(n:Attachment AND n.name CONTAINS 'body')
RETURN COLLECT(DISTINCT {data_object_uid: do.uid})

neo4j apoc merge node from json file

I use neo4j apoc tool to load data from json file which is stored on hdfs , example of the file content like this :
{"id":"572911761","label":"Label1","nickName":"xxx","screenName":"xxx","userType":2}
{"id":"111117971217247","label2":"Label","nickName":"dada","userType":2}
{"id":"111112559184932","label3":"Label","nickName":"Kwok","screenName":"kwok","userType":2}
{"id":"1447694416","label":"Label4","nickName":"Sylar","screenName":"sylar","userType":2}
{"id":"111111154273959","label":"Label2","nickName":"Chan","screenName":"kmuhk","userType":2}
The Field of label is the label of node in neo4j, means I want set Dynamic Label by read Label from the file per line , my input cypher is :
CALL apoc.load.json("hdfs://hdp1:8020/apoc/graph/apoc_graph_20200422202753_0_nodes") yield value
call apoc.merge.node(value.label, {uid:value.uid}, {nickname:value.nickName,screen_name: value.screenName })
and it execute error, the error :
Neo.ClientError.Statement.SyntaxError
Neo.ClientError.Statement.SyntaxError: Query cannot conclude with CALL (must be RETURN or an update clause) (line 2, column 1 (offset: 98))
"call apoc.merge.node(value.label, {uid:value.uid}, {nickname:value.nickName,screen_name: value.screenName })"
^
Ask for help, thanks !
The error message is pretty helpful here, it's saying that the last line of your query must either be some kind of update to the graph (like a CREATE or a MERGE), or otherwise a RETURN statement. Here, we've got a CALL.
To fix, we want to yield the merged node from apoc.merge.node, then return it:
CALL apoc.load.json("hdfs://hdp1:8020/apoc/graph/apoc_graph_20200422202753_0_nodes") yield value
CALL apoc.merge.node(value.label, {uid:value.uid}, {nickname:value.nickName,screen_name: value.screenName }) YIELD node
RETURN node

Running 2 cypher queries for full text search returns error in neo4j

I have a task in hand where for an input job title pairs I have to output how similar these 2 titles are. For similarity I will be taking into account different factors like common relationships between 2 job title nodes etc.
I am currently into the 1st part, i.e getting a best matching job title node for input job title. I am using the full-text-search capability of neo4j to solve this. I have come up with the following query
CALL db.index.fulltext.queryNodes("full-text-job-title", '"software engineer" OR (software~0.7 engineer~0.7)') yield node, score
with collect(node)[..1] as matchedTitles1
CALL db.index.fulltext.queryNodes("full-text-job-title", '"software developer" OR (software~0.7 developer~0.7)') yield node, score
with collect(node)[..1] as matchedTitles2
return matchedTitles1[0], matchedTitles2[0]
It returns the following error
Neo.ClientError.Statement.SyntaxError
Neo.ClientError.Statement.SyntaxError: Variable `matchedTitles1` not defined (line 5, column 8 (offset: 351))
"return matchedTitles1[0], matchedTitles2[0]"
^
I am unable to solve this error. Also I want to return the top matching job-title node for each of the input job title pair. Currently I have come up with this - with collect(node)[..1] as matchedTitles1, but I think there has to be a better way to return the top matching job-title node
Any help will be deeply appreciated.
Your syntax error is because you're not passing through matchedTitles1 in your second WITH statement. Everything from before the WITH that you want to refer to after the WITH needs to be included in the WITH statement.
The following is valid Cypher:
CALL db.index.fulltext.queryNodes("full-text-job-title", '"software engineer" OR (software~0.7 engineer~0.7)') yield node, score
with collect(node)[..1] as matchedTitles1
CALL db.index.fulltext.queryNodes("full-text-job-title", '"software developer" OR (software~0.7 developer~0.7)') yield node, score
with collect(node)[..1] as matchedTitles2, matchedTitles1 // Pass through matchedTitles1 from the first CALL so it's visible in the RETURN
return matchedTitles1[0], matchedTitles2[0]

apoc refactor rename gives Procedure does not support implicit naming error

I try to write a cypher query that extracts a set of labels, that share one specific label. After is selected the labels i try to rename them. Which means add a prefix to each of the labels andrename the labels in the graph with help of apoc.refactor.rename.label. Therefore i wrote the following query.
match (c:TheLabel)
with collect(distinct filter( l in labels(c) where not l in ["UNIQUE IMPORT LABEL","TheLabel"])[0]) as curr_label
unwind curr_label as cl
with cl as cl, "AR_"+cl as nl
call apoc.refactor.rename.label(cl, nl)
return null
But this query fails with the following error message:
Neo.ClientError.Statement.SyntaxError: Procedure call inside a query does not support naming results implicitly (name explicitly using `YIELD` instead) (line 5, column 1 (offset: 214))
"call apoc.refactor.rename.label(cl, nl) return null"
I can't understand where i could use yield to get this query run.
I tried the first part separately i.e. return nl & cl after the with. This works fine. I also tried to use the rename function with one specific cl and cl that i got while trying the first part of the query. That is also working fine. Only the combination seems not to work.
Edit:
I figured out that every unwind seems to break the query never the less if I use the variable that is defined by unwind or not.
Minimal example that produces the same error:
unwind [1,2,3,4] as cl
call apoc.refactor.rename.label("Test", "Test")
return cl
Thanks in advance for any help or solutions.
If a procedure is defined to return any results, then the Cypher language requires that the CALL clause must be paired with a YIELD clause -- even if you don't care about any of the results. The only exception is when the entire Cypher statement consists of just a CALL clause (this is referred to in the docs as a "standalone procedure call").
To quote from the docs:
If the called procedure declares at least one result field, YIELD may
generally not be omitted. However YIELD may always be omitted in a
standalone procedure call. In this case, all result fields are yielded
as newly-bound variables from the procedure call to the user.
Ok after trying around i figured it out. You need to yield at least one field of the return of the call for example:
unwind [1,2,3,4] as cl
call apoc.refactor.rename.label("Test", "Test")
yield total
return null // everything is possible for return.
I don't know why it's working but it works. Maybe it has to do something with the stream that the procedure produces, but I'm really not sure. If somebody knows why it solves my problem please comment.

Execute multiple query based on multiple condition in cypher / apoc

In cypher or APOC, Is there a way to execute multiple query based on multiple condition.
I need something similar this APOC
CALL apoc.do.case([condition, query, condition, query, …​], elseQuery:'',
params:{}) yield value
But here as soon as we met 1st true condition it skip all further condition and query. I want to execute all those query where my condition is true.
In simple word , I am looking for something similar to java case statement (without break; between case)
Update
I ran following query to use multiple apoc.do.when but it seems only my second apoc.do.when is not executing:
CREATE (y:EVENT { _id: 1, localComponentID:'l1', externalComponentID:'e1'}) with y
call apoc.do.when(exists(y.localComponentID),"MATCH(e:EVENT) where
e.localComponentID = lcl and e._id <> y._id with y,e limit 1 create (y)-
[r:LOCAL_LINK]->(e)",'',{y:y,lcl:y.localComponentID}) YIELD value WITH value AS ignored, y
call apoc.do.when(exists(y.externalComponentID),"MATCH(e:EVENT) where
e.externalComponentID = ext and e._id <> y._id with y,e limit 1 create (y)-
[r:EXTERNAL_LINK]->(e)",'',{y:y, ext:y.externalComponentID}) YIELD value
WITH value AS ignored return ignored
If I run above query two time with _id = 1 in first run and _id=2 in second run, I expect two EVENT connected with LOCAL_LINK and EXTERNAL_LINK. But I am only getting LOCAL_LINK between them not the EXTERNAL_LINK. I am not sure what I am doing wrong.
Note : I am using limit 1 because In case of multiple match I just want to create LINK with one node.
Update 2
Got it working , In my sample query I was that not returning y from first apoc.do.when
Here is the updated query which works:
CREATE (y:EVENT { _id: 1, localComponentID:'l1', externalComponentID:'e1'}) with y
call apoc.do.when(exists(y.localComponentID),"MATCH(e:EVENT) where
e.localComponentID = lcl and e._id <> y._id with y,e limit 1
create (y)-[r:LOCAL_LINK]->(e) RETURN y",'',
{y:y,lcl:y.localComponentID}) YIELD value WITH value AS ignored, y
call apoc.do.when(exists(y.externalComponentID),"MATCH(e:EVENT) where
e.externalComponentID = ext and e._id <> y._id with y,e limit 1
create (y)-[r:EXTERNAL_LINK]->(e)",'',{y:y, ext:y.externalComponentID})
YIELD value
WITH value AS ignored return ignored
You can just call the APOC function apoc.do.when for each condition/query pair (with an empty string as the else argument).
For example:
CALL apoc.do.when(<condition1>, <query1>, '', {}) YIELD value
WITH value AS ignored
CALL apoc.do.when(<condition2>, <query2>, '', {}) YIELD value
WITH value AS ignored
.
.
.
Since your comments indicate your queries are all write-only, the above example assigns the return values to an ignored variable (that you can ignore).

Resources