我有一个标题中指定的问题。例如,这是我当前的查询:
MERGE (n:Person { name: 'John' })
ON CREATE SET n.age = 30
ON MATCH SET n.age = 30
我想要一个不区分大小写的搜索。因此,name
可能john, JOHN, joHN
,并不重要,它应该仍然匹配。
据我所知,我们可以通过在WHERE
子句中使用正则表达式来实现不区分大小写的搜索。例如:
MATCH (n:Person)
WHERE n.name =~ '(?i)John'
但是,MERGE
子句不支持WHERE
子句。说无效:
MERGE (n:Person)
WHERE n.name =~ '(?i)John'
ON CREATE SET n.age = 30
ON MATCH SET n.age = 30
那么,在这种情况下解决方案是什么?我发现的一个建议是使用OPTIONAL MATCH
。查询将是:
OPTIONAL MATCH (n:Person) WHERE n.name =~ '(?i)John'
WITH n
WHERE n IS NOT NULL SET n.age = 30
OPTIONAL MATCH (n:Person) WHERE n.name =~ '(?i)John'
WITH n
WHERE n IS NULL MERGE (n:Person { name: 'John', age: 30 })
您对此解决方案有何看法?你有什么建议吗?非常感谢你的帮助。
答案 0 :(得分:1)
[EDITED]
选项1。
如果可以在一致的情况下(例如,大写)向每个包含名称的Person
节点添加新属性,则有一种解决方法。
解决方法需要您首先将新属性添加到所有Person
个节点。例如:
MATCH (p:Person)
SET p.uName = TOUPPER(p.name);
添加新属性后,您可以直接使用MERGE
。 在以下查询中,我假设您要查找的年龄和名称将作为parameters $age
和$name
传递给查询。
MERGE (p:Person {uName: TOUPPER($name)})
ON CREATE SET p.name = $name
SET p.age = $age;
如果刚刚创建了节点,则此查询将设置name
属性。此外,由于您始终要设置年龄,因此此查询始终执行此操作。
选项2。
如果您不想添加新属性,可以使用APOC过程apoc.do.when来选择性地创建Person
节点并获取可选的已创建节点(或现有节点)进一步处理它。例如:
OPTIONAL MATCH (n:Person)
WHERE n.name =~ ('(?i)' + $name)
CALL apoc.do.when(
n IS NULL,
'CREATE (p:Person {name: $name}) RETURN p',
'RETURN $existing AS p',
{name:$name, existing: n}) YIELD value
WITH value.p AS p
SET p.age = $age
RETURN p;