Cannot merge the following node because of null property value for 'title_name': (:Period {title_name: null})
Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
07-04-2022 08:57 PM
Hello guys,
my question is if there is a way to ignore a MERGE-line if a variable "if not exists".
I have many xml-Files with some fields that dont exist in all my files, so I have to think about a solution
with an option to ignore MERGE-Code.
Example:
Cannot merge the following node because of null property value for 'title_name': (:Period {title_name: null})
07-05-2022 04:49 AM
Hi @dionisios95
Yes, you can either check it with a where condition or by using apoc.do.when like the following:
I hope this solves your question.
07-05-2022 12:04 PM - edited 07-05-2022 12:06 PM
Thx for your help, but unfortunately it does not work if I have multiple merge.
To option1: I have to put the where`s in separatly for each merge, but it doenst work with "{}" or "," and with the where -> merge ->where order it also does not work.
.......
Query cannot conclude with CALL together with YIELD (line 76, column 1 (offset: 3360)) "CALL apoc.do.when( mstitle IS NOT NULL, "MERGE(m{title_name: mstitle._text}) RETURN 'created' ", "RETURN True",{}) YIELD value2 as v2"
07-05-2022 08:08 PM
If you have a sequence of 'merge' statements that you need to individually test for, you can do it by wrapping each merge in a 'call' subquery. The following is an example, where the first merge is not executed, but the second one is. This only works if the subqueries do not return a value. The 'double with' syntax is odd, but it gets around the fact that you can only import simple statements in a 'call' subquery, thus the first 'with' is 'simple' and the second 'with' can have a 'where' clause after it.
with null as x, 'a' as y
call {
with x
with x
where not x is null
merge(a:Test {name:'null'})
}
call {
with y
with y
where y = 'a'
merge(a:Test {name:'a'})
}
07-06-2022 02:59 AM - edited 07-06-2022 03:05 AM
Thank you very much, but it seems not allright. I put this subquery-part at the end, because I have more other MERGE-parts.
My Code:
.......
07-06-2022 03:07 AM - edited 07-06-2022 03:11 AM
You need to import existing nodes that you want to use in a subquery. In your second subquery, you refer to ‘t’. Since ‘t’ is not defined in the subquery, it creates a new node and binds it to variable ‘t’. Add ‘t’ to the with statements to import it into the subquery, so it will use it instead of creating a new node.
07-06-2022 08:42 AM - edited 07-06-2022 08:52 AM
There is a t as t definition in the WITH-part and t is known outside, because I need the t also on the outside of the query for other merge-parts. Unfortunately I will get:
(new unlabeled Node) -[:CONTAINS]-> (unknown labeled Node with right propertie-key-values)
Although I am getting the right Trial-Node at return after the WITH.
07-08-2022 08:45 AM
You just need to import the value of 't' into the 'call' subquery by including it in the subquery's 'with' statements.
I can help if you provide the entire query.
07-07-2022 12:23 AM
Try this:
[x in mstitle where x._type = COALESCE('title'][0], 'NA') as mstitle
07-07-2022 10:34 AM
I've tried that:
...
Cannot merge the following node because of null property value for 'title_name': (:Period {title_name: null})
07-07-2022 05:34 PM
How about ignoreME in CASE WHEN?
FOREACH (ignoreMe in CASE WHEN title IS NOT NULL then [1] ELSE [] END | MERGE (p:Period {title_name:title._text}) SET p.otherproperty=title._othervalue)
07-08-2022 01:27 AM - edited 07-08-2022 01:28 AM
This one works on this code without an Error on both files well, but...:
.....
{
"identity": 362,
"labels": [
"Period"
],
"properties": {
}
}
07-08-2022 06:28 AM - edited 07-08-2022 06:42 AM
Try the MERGE (p:Period) INSIDE the FOREACH clause, not before it.
If you need to do some modifications with (p:Period) AFTER the FOREACH clause you could follow-up with an OPTIONAL MATCH (p:Period {title_name:title._text}) then perform additional matches/property modifications..
FOREACH (ignoreMe in CASE WHEN title IS NOT NULL then [1] ELSE [] END | MERGE (p:Period {title_name:title._text}) SET p.otherproperty=title._othervalue)
OPTIONAL MATCH (p:Period {title_name:title._text})
... Other MATCH/RELATIONSHIP or PROPERTY work with p:Period goes here
THE FOREACH will only run when it is NOT NULL, but it won't stop execution because of NULL.
The OPTIONAL MATCH will MATCH p IF it exists, but again, will continue execution even if it doesn't.
The second MATCH does create some inefficiency (you are doing a MERGE and a MATCH on the same node) - so not sure if volume of data is an issue for you here.
07-08-2022 04:19 PM - edited 07-08-2022 04:20 PM
I tried:
.........
Failed to create relationship ` UNNAMED0`, node ` p@41` is missing. If you prefer to simply ignore rows where a relationship node is missing, set 'cypher.lenient_create_relationship = true' in neo4j.conf
07-09-2022 06:50 AM
Because you are using OPTIONAL MATCH you have to protect against merging a null value - so the relationship would have to be:
FOREACH(ignoreMe in CASE WHEN p.title_name IS NOT NULL then [1] ELSE [] END | MERGE (t)-[:CONTAIN]->(p))
Also - unless this doesn't work with your logic, I'd do as much as you can within the first FOREACH case to keep it clean like this:
with [x in title where x._type = 'title'][0] as title,
[x in nctid where x._type = 'nct_id'][0] as nctid
MERGE(t:Trial{nct_id:nctid._text})
FOREACH(ignoreMe in CASE WHEN title IS NOT NULL then [1] ELSE [] END | MERGE(p:Period{title_name:title._text}) MERGE (t)-[:CONTAIN]->(p) )
with t,title, nctid // You are Correct - I forgot this in my example - MATCH after a MERGE always needs WITH to bring along any variables you need
OPTIONAL MATCH (p:Period{title_name:title._text})
... Now do other stuff
07-09-2022 09:06 AM
As @pdrangeid suggested, you should do all you can within the call/foreach clause, so you don't have to worry about retrieving the node later and then also checking if returned as 'null'.
with [x in title where x._type = 'title'][0] as title,
[x in nctid where x._type = 'nct_id'][0] as nctid
MERGE(t:Trial{nct_id:nctid._text})
call {
with title, t
with title, t
WHEN title IS NOT NULL
MERGE(p:Period{title_name:title._text})
MERGE (t)-[:CONTAIN]->(p)
//finish your use of 'p' within the 'call' clause
}
07-09-2022 08:48 PM - edited 07-09-2022 08:49 PM
Ok I think it worked with multiple times of foreach in foreach. I just had to think about the positions of the merge's:
All the sessions of the conference are now available online