合并语句以匹配多个属性

时间:2015-10-27 04:54:54

标签: neo4j cypher

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

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

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

public function summeriseProduction() {

// Unescape the string values in the JSON array
 $supervisorIdArray = stripcslashes($this->input->post('checkedRows'));
 $paymentPeriodId = $this->input->post('paymentPeriodId');
 // Decode the JSON array
   $supervisorIdArray1 = json_decode($supervisorIdArray, TRUE);
 // $paymentPeriodId1 = json_decode($paymentPeriodId, TRUE);

 echo json_encode($supervisorIdArray1);
//    echo $paymentPeriodId;

}

我在想我可以使用批处理或交易。如果我还在学习Cypher,我将不胜感激任何见解或指导。

2 个答案:

答案 0 :(得分:2)

不确定您是否可以在一个声明中执行此操作,我将关注此问题以查看是否存在更优的路线。 您可以在两个位置找到并更新现有节点,第二个将找到并创建缺少的节点:

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,然后update语句将与节点匹配,但会将A重置为null(当然,除非您确保更新只设置非空值)。

答案 1 :(得分:-1)

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

合并,如何运作

根据neo4j's documentation,如果节点不存在,则可以使用您指定的节点属性来知道该节点是否已存在。

事实上,您不需要此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"无法合并:

BackStackRecord.java line 797 android.app.BackStackRecord.run

要做你想做的事情,你必须把你的合并分成多个部分,我想,但是如果我找到了怎么回事,我就不知道如何编辑答案。