【问题标题】:Merge statement to match multiple properties合并语句以匹配多个属性
【发布时间】:2015-10-28 04:48:10
【问题描述】:

我试图弄清楚如何使用密码查询有效地添加新节点。我正在尝试合并多个数据源,因此需要寻找可能的匹配数据。我有 3 个可能存在或不存在的数据点。如果任何数据点匹配,我想重用现有节点。如果没有一个数据点匹配,我想创建一个新节点。

如果节点不存在则创建节点是 MERGE 的确切用例。 MERGE 不允许 WHERE 子句,否则这将非常简单。由于我正在匹配数据点-a 或数据点-b 或数据点-c,我无法弄清楚如何使用 MERGE,因为它是所有属性。

这是无效的,但应该表达我的目标:

MERGE (n:TYPE)
WHERE n.propertyA = "A" OR n.propertyB = "B" OR n.propertyC = "C"
ON MATCH SET n.propertyA = "A", n.propertyB = "B", n.propertyC = "C"  
ON CREATE SET n.timestamp = <now>, n.propertyA = "A", n.propertyB = "B", n.propertyC = "C"
RETURN n;

我在想我也许可以使用批处理或事务。由于我仍在学习 Cypher,因此我将不胜感激任何见解或指导。

【问题讨论】:

  • 试图完成同样的事情。你找到你喜欢的解决方案了吗?

标签: neo4j cypher


【解决方案1】:

不确定您是否可以在单个语句中做到这一点,我将关注这个问题,看看是否有更优化的路线。 您可以分两种方式进行,第一种是查找和更新现有节点,第二种是查找并创建缺失的节点:

OPTIONAL MATCH (existing:TYPE) WHERE existing.propertyA = 'A' OR existing.propertyB = 'B' OR existing.propertyC = 'C'
WITH existing
WHERE existing IS NOT NULL SET existing.propertyA = 'A', existing.propertyB = 'B', existing.propertyC = 'C'
RETURN existing;

OPTIONAL MATCH (existing:TYPE) WHERE existing.propertyA = 'ZZ' OR existing.propertyB = 'ZZ' OR existing.propertyC = 'ZZ'
WITH existing
WHERE existing IS NULL MERGE (newNode:TYPE {propertyA: 'ZZ', propertyB: 'ZZ', propertyC: 'ZZ'})
RETURN newNode

但是,请注意,这不会保留现有值 - 例如如果从一个源属性 A 和 B 加载(并且 C 为空),然后从第二个源加载并且 A 为空但设置了 B 和 C,则更新语句将匹配节点,但会将 A 重置为空(当然,除非您确保您的更新仅设置非空值)。

【讨论】:

    【解决方案2】:

    我不知道我是否完全理解了这个问题,但这应该对你有所帮助:

    合并,它是如何工作的

    根据neo4j's documentationmerge可以用来创建一个节点,如果它不存在,使用你指定的节点属性来知道节点是否已经存在。

    事实上,这里不需要WHERE 子句来匹配节点的属性。

    所以这个:

    MERGE (n:TYPE)
    WHERE n.propertyA = "A" OR n.propertyB = "B" OR n.propertyC = "C"
    ON MATCH SET n.propertyA = "A", n.propertyB = "B", n.propertyC = "C"  
    ON CREATE SET n.timestamp = timestamp(), n.propertyA = "A", n.propertyB = "B", n.propertyC = "C"
    RETURN n;
    

    正如你所说,这是错误的。差不多可以这样实现:

    MERGE (n:TYPE {propertyA : "A"})
    ON MATCH SET n.propertyA = "A", n.propertyB = "B", n.propertyC = "C"  
    ON CREATE SET n.timestamp = timestamp(), n.propertyA = "A", n.propertyB = "B", n.propertyC = "C"
    RETURN n;
    

    如果我完全理解您想要做什么,那是不可能的。因为MERGE要么匹配要么创建节点。您想使用OR 进行合并,但由于无法创建节点,因此无法执行此操作:

    CREATE (a:Node) SET a.propertyA = "A" OR a.propertyB = "B"

    要做你想做的事,我猜你必须将你的合并拆分成多个部分,但我不知道实际上如何,如果我找到了如何编辑答案。

    【讨论】:

    • 您在这里给出了两个不同的答案。第一个忽略 OP 的请求(匹配任一键,而不是所有键)。第二个确实(“这是不可能的”),但给出了不相关的解释(他们无意以这种方式创建节点)。请修改您的答案。
    猜你喜欢
    • 2016-11-29
    • 1970-01-01
    • 1970-01-01
    • 2020-01-28
    • 1970-01-01
    • 2010-09-14
    • 1970-01-01
    • 2020-05-08
    • 2011-07-09
    相关资源
    最近更新 更多