写条款的效果不可见

时间:2016-09-21 10:17:18

标签: neo4j cypher

使用Neo4j 3.0.4

如果路径上存在可选匹配项,则有条件地创建顶点:

with [
 {customer: 0001, created: 1474434591, version: "1.0.0"},
 {customer: 0001, created: 1474434500, version: "1.0.0"},
 {customer: 0003, created: 1474445743, version: "1.1.0"}
] as lines 
unwind lines as line
/// customers above already exist
MATCH (c:Customer {id: line.customer})
OPTIONAL MATCH (c)-[:HAS]->(co:Configuration) WHERE co.created >= line.created
WITH CASE WHEN co IS NULL THEN
  [1]
END as createInventory,
CASE WHEN co IS NOT NULL THEN 
  [count(co)]
END as throwError, c, line
FOREACH (x in createInventory |
  CREATE (n:Configuration {
   created: line.created,
   version: line.version
  })
  CREATE UNIQUE (c)-[:HAS]->(n)
)
FOREACH (x in throwError |
  CREATE (e:Error:Inventory { message: "Configuration " + line.created + " >= existing (" + x + ")" })
);

期望只创建2 Configuration个顶点并与Customer相关联。而是创建了所有3个Configuration个实例。写语句(即create)在同一个事务中,因此我假设在循环OPTIONAL MATCH时不反映单个写操作。在此示例中,行是Configuration,如果创建的属性比现有属性旧,我不想创建与同一Customer绑定的新行。因此OPTIONAL MATCH中的谓词。

在同一事务(或Cypher语句)中有条件地创建和考虑写入的任何方式?

1 个答案:

答案 0 :(得分:2)

Cypher永远不会"循环"回到之前的条款。

您可以通过在UNWIND子句后面插入此子句来获得您的期望:

WITH
  line.customer AS lc,
  REDUCE(s = NULL, x IN COLLECT(line) | CASE WHEN s IS NULL OR x.created > s.created THEN x ELSE s END) AS line

WITH子句根据不同的line.customer值获取linecreated,删除任何其他行。 (这是"每个客户"的原因是因为使用了COLLECT aggregation function within that WITH clause)。

顺便说一句,您的查询使用CREATE UNIQUE而不是CREATE是没有意义的,因为之前创建的n节点是全新的,因此指定的模式以前不存在。