如何在MERGE子句中使用不区分大小写的匹配?

问题描述 投票:0回答:1

我有一个标题中指定的问题。例如,这是我当前的查询:

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 })

您对此解决方案有何看法?你有什么建议吗?非常感谢你的帮助。

neo4j cypher case-insensitive
1个回答
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;
© www.soinside.com 2019 - 2024. All rights reserved.