我有一个密码查询(如下)。 它有效,但我想知道是否有更优雅的方式来写这个。
基于给定的起始节点,查询尝试:
找到以下模式/主题:(inputko)-->(:cpd)-->(ko2:ko)-->(:cpd)-->(ko3:ko)
。
找到找到的图案/模式,找到带有标签contigs
的连接节点,用于模式中的以下节点:[inputko
,ko2
,ko3
]。
3个节点及其连接的重叠群的总结,即。 3个节点的名称属性.ko
以及找到的每个:contig
主题中连接的(inputko)-->(:cpd)-->(ko2:ko)-->(:cpd)-->(ko3:ko)
个节点的数量。
+--------------------------------------------------------------------------+
| KO1 | KO1count | KO2 | KO2count | KO3 | KO3count |
+--------------------------------------------------------------------------+
| "ko:K00001" | 102 | "ko:K14029" | 512 | "ko:K03736" | 15 |
| "ko:K00001" | 102 | "ko:K00128" | 792 | "ko:K12972" | 7 |
| "ko:K00001" | 102 | "ko:K00128" | 396 | "ko:K01624" | 265 |
| "ko:K00001" | 102 | "ko:K03735" | 448 | "ko:K00138" | 33 |
| "ko:K00001" | 102 | "ko:K14029" | 512 | "ko:K15228" | 24 |
+--------------------------------------------------------------------------+
我对在每场比赛中操作的语法感到困惑。
从文档来看,foreach
子句似乎不是我需要的。
任何想法的家伙?
FOREACH子句用于更新集合中的数据,无论是否 路径的组成部分或聚合的结果。
集合和路径是Cypher的关键概念。使用它们 更新数据,您可以使用FOREACH构造。它允许你这样做 更新集合中元素的命令 - 路径或 聚合创建的集合。
START
inputko=node:koid('ko:\"ko:K00001\"')
MATCH
(inputko)--(c1:contigs)
WITH
count(c1) as KO1count, inputko
MATCH
(inputko)-->(:cpd)-->(ko2:ko)-->(:cpd)-->(ko3:ko)
WITH
inputko.ko as KO1,
KO1count,
ko2,
ko3
MATCH
(ko2)--(c2:contigs)
WITH
KO1,
KO1count,
ko2.ko as KO2,
count(c2) as KO2count,
ko3
MATCH
(ko3)--(c3:contigs)
RETURN
KO1,
KO1count,
KO2,
KO2count,
ko3.ko AS KO3,
count(c3) AS KO3count
LIMIT
5;
意识到我必须在count(distinct cX)
中放置明确的内容以获得准确的计数。不知道为什么。
答案 0 :(得分:1)
我不确定优雅这是怎么回事,但我认为它确实为您提供了一些关于如何扩展查询路径中n
个ko节点并仍然返回数据的概念正如你在下面列出的那样。它还应该展示组合with
指令和集合的强大功能。
// match the ko/cpd node paths starting with K00001
match p=(ko1:ko {name:'K00001' } )-->(:cpd)-->(ko2:ko)-->(:cpd)-->(ko3:ko)
// remove the cpd nodes from each path and name the collection row
with collect([n in nodes(p) where labels(n)[0] = 'ko' | n]) as row
// create a range for the number of rows and number of ko nodes per row
with row
, range(0, length(row)-1, 1) as idx
, range(0, 2, 1) as idx2
// iterate over each row and node in the order it was collected
unwind idx as i
unwind idx2 as j
with i, j, row[i][j] as ko_n
// find all of the contigs nodes atttached to each ko node
match ko_n--(:contigs)
// group the ko node data together in a collection preserving the order and the count
with i, [j, ko_n.name, count(*)] as ko_set
order by i, ko_set[0]
// re-collect the ko node sets as ko rows
with i, collect(ko_set) as ko_row
order by i
//return the original paths in the ko node order with the counts
return reduce( ko_str = "", ko in ko_row |
case
when ko_str = "" then ko_str + ko[1] + ", " + ko[2]
else ko_str + ", " + ko[1] + ", " + ko[2]
end) as `KO-Contigs Counts`
cypher中的foreach
指令严格用于改变数据。例如,您可以使用一个查询来收集每个contigs
节点的ko
个计数。
这有点令人费解,你永远不会像这样更新contigs
节点上ko
的数量,但它说明了在{cypher中使用foreach
。
match (ko:ko)-->(:contigs)
with ko,count(*) as ct
with collect(ko) as ko_nodes, collect(ct) as ko_counts
with ko_nodes, ko_counts, range(0,length(ko_nodes)-1, 1) as idx
foreach ( i in idx |
set (ko_nodes[i]).num_contigs = ko_counts[i] )
在每个ko
节点上执行上述更新任务的更简单方法是执行以下操作...
match (ko:ko)-->(:contigs)
with ko, count(*) as ct
set ko.num_contigs = ct
如果您要在每个ko节点上携带多个重叠群,那么您可以执行这样的查询以返回
的数量// match all the paths starting with K00001
match p=(ko1:ko {name:'K00001' } )-->(:cpd)-->(ko2:ko)-->(:cpd)-->(ko3:ko)
// build a csv line per path
return reduce( ko_str = "", ko in nodes(p) | ko_str +
// using just the ko nodes in the path
// exclude the cpd nodes
case
when labels(ko)[0] = "ko" then ko.name + ", " + toString(ko.num_contigs) + ", "
else ""
end
) as `KO-Contigs Counts`