我尝试在我的查询中使用UNION创建发票产品子图,然后只想将使用WITH的发票节点传递给子查询。它看起来像下面
MATCH (year:Year)-[]->(month:Month)-[]->(day:Day)-[]->(inv:Invoice)-[]->(prd:Product)
WHERE year.value='2014' and day.value IN ['27','28','29','30','31'] and month.value='January'
RETURN (inv:Invoice)-[:PRODUCT]->(prd:Product)
UNION
MATCH (year:Year)-[]->(month:Month)-[]->(day:Day)-[]->(inv:Invoice)-[]->(prd:Product)
WHERE year.value='2014' and day.value IN ['01','02','03','04'] and month.value='February'
WITH inv
MATCH (inv)-[p:PROCESSED_AT]-(time:Time) WHERE p.time > 700 and p.time < 900
RETURN inv.invid
但我收到此错误 - UNION中的所有子查询必须具有相同的列名。关于我在哪里出错的任何输入?
答案 0 :(得分:1)
我认为错误很明显,你的UNION的两个部分没有返回相同数量的列来建立联合。如果我理解正确,您正在尝试获取具有无效时间戳的特定产品的所有发票。我不认为如果是这种情况你将需要一个UNION,你可能需要一个WITH子句。
无论如何,要修复上述查询,您可能只想匹配UNION的两个部分,如下所示
MATCH (year:Year)-[]->(month:Month)-[]->(day:Day)-[]->(inv:Invoice)-[]->(prd:Product)
WHERE year.value='2014' and day.value IN ['27','28','29','30','31'] and month.value='January'
MATCH (inv:Invoice)-[:PRODUCT]->(prd:Product)
RETURN inv, prd
UNION
MATCH (year:Year)-[]->(month:Month)-[]->(day:Day)-[]->(inv:Invoice)-[]->(prd:Product)
WHERE year.value='2014' and day.value IN ['01','02','03','04'] and month.value='February'
WITH inv
MATCH (prd:Product)<-[:PRODUCT]-(inv)-[p:PROCESSED_AT]-(time:Time) WHERE p.time > 700 and p.time < 900
RETURN inv, prd
修改强>
我认为你有UNION
,RETURN
和WITH
一点点,说实话我不知道如何使用UNION加入2个结果然后使用WITH
将其缝合到另一个查询。但是我认为你可以通过简单的重新排列连接来解决这个问题,如下所示
MATCH (year:Year)-[]->(month:Month)-[]->(day:Day)-[]->(inv:Invoice)-[]->(prd:Product)
WHERE year.value='2014' and ((day.value IN ['27','28','29','30','31'] and month.value='January') or (day.value IN ['01','02','03','04'] and month.value='February'))
WITH inv
MATCH (inv)-[p:PROCESSED_AT]-(time:Time) WHERE p.time > 700 and p.time < 900
RETURN inv.invid
答案 1 :(得分:0)
您可以将逗号分隔的多个短语传递给MATCH,只要它们构成一个连接的图形,这样可以简化您的问题。
MATCH (year:Year)-[]->(month:Month)-[]->(day:Day)-[]->(inv:Invoice)-[]->(prd:Product)
WHERE year.value='2014' and day.value IN ['01','02','03','04'] and month.value='February'
WITH inv
MATCH (prd:Product)<-[:PRODUCT]-(inv)-[p:PROCESSED_AT]-(time:Time) WHERE p.time > 700 and p.time < 900
RETURN inv, prd
可以成为:
MATCH (year:Year)-[]->(month:Month)-[]->(day:Day)-[]->(inv:Invoice)-[]->(prd:Product),
(prd:Product)<-[:PRODUCT]-(inv)-[p:PROCESSED_AT]-(time:Time)
WHERE p.time > 700 and p.time < 900
RETURN inv, prd
您可以类似地简化查询的前半部分。
此外,使用union时,返回的列名必须与每个return子句匹配。
答案 2 :(得分:0)
我最终通过改变整体设计来解决这个问题,这将避免UNION的使用。一种方法是将时间戳定义为单个实体,而不是将它们分别存储为年,月和日。
即。添加如下节点
//Add TimeStamp Nodes
CREATE (datets1: DateTS {value:201401270730})
CREATE (datets2: DateTS {value:201401270800})
CREATE (datets3: DateTS {value:201401280745})
CREATE (datets4: DateTS {value:201402020815})
CREATE (datets5: DateTS {value:201402020830})
CREATE (datets6: DateTS {value:201402030702})
注意 - 在我的情况下,我不需要秒和毫秒,所以它最终会以小时和分钟的分辨率结束。
现在我将图表中的事件与这些节点相关联,然后查询变得非常简单,类似于
MATCH (inv)-[:DATETIME]->(dts) WHERE dts.value <=201401280900 and dts.value >= 201401280700
RETURN distinct(inv.invid);
为了提高此查询的性能,我们可以为时间戳索引,即值属性。