我有公司指标数据,我想查询
----------------------------------------------------
|Metrics | Year | Qtr | Department | Value|
----------------------------------------------------
|Revenue| 2017 | Q1 | Dep1 | 2000045|
|Revenue| 2017 | Q2 | Dep1 | 2000046|
|Revenue| 2017 | Q2 | Dep2 | 2000047|
|Revenue| 2017 | Q3 | Dep2 | 2000048|
|Revenue| 2017 | Q3 | Dep3 | 2000049|
|Sales | 2017 | Q1 | Dep1 | 2000041|
|Sales | 2017 | Q1 | Dep2 | 2000052|
|Sales | 2017 | Q2 | Dep1 | 2000053|
-----------------------------------------------------
现在我像这样建模上面的数据
年,Qtr和部门作为节点,如
(d:DIM {name:"2012","type":"year")
像
这样的节点值 (v:VALUE {value:2000053})
和指标作为关系,如
(d:DIM {name:"2012","type":"year") - [:REVENUE]-> (v:VALUE {value:2000053})
因此,对于每条记录,VALUE节点可能存在三种关系。
现在出现了查询部分:
给定维度,查询应该获取值,如给定年份2017,Qtr q1应该返回与此过滤器对应的值,如果我添加Dep 1,那么它应该进一步过滤结果。
我尝试了一些像
这样的查询Match (d:DIM)-[:REVENUE]->(v:VALUE)
where d.name in ["2017","q1"]
Return d,v
但是这个查询提供了2017年的UNION和q1而不是我正在寻找的交集。
此外,我可以使用类型属性进行分组。
答案 0 :(得分:0)
有几种方法可以做到这一点。虽然我个人建议为Year,Qtr和Department使用单独的节点标签(也可能是Metrics),但我会使用您当前的模型。
交集所需的部分是ALL()谓词,它在值列表上运行。在这种情况下,我们将收集所有匹配的:DIM节点。为了使匹配有效,我们希望匹配列表中第一项的v
个节点,然后确保v
连接到列表中的其余项目(比从所有项目中过滤更快: VALUE节点)。
match (d:DIM)
where d.name in ["2017","q1"]
with collect(d) as dims
with head(dims) as head, tail(dims) as dims
match (head)-[:REVENUE]->(v)
where all(dim in dims where (dim)-[:REVENUE]->(v))
return dims, v
或者,如果您安装了APOC Procedures,则可以使用交叉功能:
match (d:DIM)-[:REVENUE]->(v)
where d.name in ["2017","q1"]
with d, collect(v) as values
with collect(d) as dims, collect(values) as allValues // list of lists
with dims, reduce(inter = head(allValues), values in tail(allValues) | apoc.coll.intersection(inter, values)) as values
return dims, values
修改
我记得另一种可能更快的方法。试试这个:
with ["2017","q1"] as dimInput
with dimInput, size(dimInput) as dimCnt
match (d:DIM)
where d.name in dimInput
match (d)-[:REVENUE]->(v)
with v, dimCnt, count(distinct d) as cnt
where dimCnt = cnt
return v