Neo4j Cypher:限制所选节点的返回链接数
我在一个显然很简单的问题上失败了 算法:Neo4j Cypher:限制所选节点的返回链接数,neo4j,cypher,Neo4j,Cypher,我在一个显然很简单的问题上失败了 算法: 按某个值对节点排序(desc): 对于每个节点,返回其直接邻居(按第二个值排序): 挑战在于返回前100个n节点,每个节点仅返回10个关系r(如果可能,在一行中) 编辑: 对不起,我说的太不具体了,以至于人们误解了我 详细地说,下面的查询为我提供了排序的顶部节点: MATCH (n) WHERE HAS(n.II_VAL) WITH n, n.`II_VAL` AS ShInflInd ORDER BY ShInflInd DESC RETURN n
MATCH (n) WHERE HAS(n.II_VAL)
WITH n, n.`II_VAL` AS ShInflInd ORDER BY ShInflInd DESC
RETURN n.NAME LIMIT 100;
+--------------------------------------+
| n.NAME |
+--------------------------------------+
| "PUBLIC" |
| "BARCLAYS PLC" |
现在,我可以将子查询添加到此中,其中添加了链接:
MATCH (n) WHERE HAS(n.II_VAL)
WITH n, n.`II_VAL` AS ShInflInd ORDER BY ShInflInd DESC LIMIT 100
MATCH (n)-[r]->(m) WHERE HAS(m.VALUE)
WITH r, n, m, m.VALUE AS SubsOpRev
RETURN n.NAME, r.WEIGHT_MERGED, m.NAME, SubsOpRev LIMIT 10;
+----------------------------------------------------------------------------------------+
| n.NAME | r.WEIGHT_MERGED | m.NAME | SubsOpRev |
+----------------------------------------------------------------------------------------+
| "PUBLIC" | 0.66 | "VBS MUTUAL BANK" | 2630 |
| "PUBLIC" | 0.2923 | "STRATCORP LIMITED" | 10842 |
现在我想要的是,在返回“PUBLIC”的10个链接(可能按r.WEIGHT_MERGED或subsprov排序)之后,查询返回第二个节点(“巴克莱PLC”)及其10个链接,等等
我试过:
MATCH (n) WHERE HAS(n.II_VAL)
WITH n, n.`II_VAL` AS ShInflInd ORDER BY ShInflInd DESC
MATCH (n)-[r]->(m) WHERE HAS(m.VALUE)
WITH r, n, m, m.VALUE AS SubsOpRev
RETURN collect([n.NAME, r.WEIGHT_MERGED, m.NAME, SubsOpRev])[0..10];
导致:
+------------------------------------------------------------------------------------------------------------------------------------------+
| collect([n.NAME, r.WEIGHT_MERGED, m.NAME, SubsOpRev])[0..3] |
+------------------------------------------------------------------------------------------------------------------------------------------+
| [["PUBLIC",0.66,"VBS MUTUAL BANK",2630],["PUBLIC",0.2923,"STRATCORP LIMITED",10842], ...
这意味着我仍然坚持“公开”
稍微修改查询会使情况变得更糟,因为它返回完全不同的数据:
MATCH (n) WHERE HAS(n.II_VAL)
WITH n, n.`II_VAL` AS ShInflInd ORDER BY ShInflInd DESC
MATCH (n)-[r]->(m) WHERE HAS(m.VALUE)
WITH r, n, m, m.VALUE AS SubsOpRev
RETURN n.NAME, collect([r.WEIGHT_MERGED, m.NAME, SubsOpRev])[0..10] LIMIT 3;
+------------------------------------------------------------------------------+
| n.NAME | collect([r.WEIGHT_MERGED, m.NAME, SubsOpRev])[0..10] |
+------------------------------------------------------------------------------+
| "RS-INVEST AS" | [[0.5,"VERUCO EIENDOM AS",100]] |
| "DBM" | [[0.1435,"CHELYABINSKOBLGAZ",6752]] |
理想情况下,查询应该产生如下结果
| [["PUBLIC",0.66,"VBS MUTUAL BANK",2630],["PUBLIC",0.2923,"STRATCORP LIMITED",10842], ... |
| [["BARCLAYS PLC",x,"XYZ",y], ... |
你能描述一下问题是什么吗 最大的问题似乎是您没有使用
返回完成查询<代码>与
用于中间传递数据。此外,实际上不需要提取值来对其进行排序。您可以这样做:
MATCH (n)
WHERE has(n.II_VAL)
RETURN n ORDER BY n.II_VAL DESC LIMIT 100
关于第二个问题:
MATCH (n)-[r]->(m)
RETURN n, m ORDER BY m.VALUE DESC LIMIT 100
编辑:对不起,忘记了
限制
要根据第一次查询获得前100个节点,必须在订单后添加返回
子句和限制
子句:
MATCH (n)
WHERE has(n.II_VAL)
RETURN n, n.II_VAL as ShInflInd
order by ShInflInd desc
LIMIT 100
对于第二个,您必须执行两个查询,并在客户端实现Foreach逻辑。因为您不能将第一个限制为100,然后在同一查询中为每个节点获取10个相关节点。您可以将节点数限制为100:
MATCH (n)
WHERE has(n.II_VAL)
WITH n, n.II_VAL AS ShInflInd
ORDER BY ShInflInd DESC
LIMIT 100
您可以收集所有subprev
,然后RETURN
收集的片段。沿着这条线(我假设subprev
就是您想要的):
这将为您提供每行一个节点
n
,以及所有收集的subsprev
列表的一部分。我想您的意思是希望在一个查询中返回两组结果。要做到这一点,我认为最好的办法是在中用收集,这只会给您一行,然后返回该值以及其他数据的收集。比如:
MATCH (n) WHERE HAS(n.II_VAL)
WITH collect([n, n.`II_VAL`])[0..100] AS set1 ORDER BY n.`II_VAL` DESC
MATCH (n)-[r]->(m) WHERE HAS(m.VALUE)
RETURN set1, collect([n.NAME, r.WEIGHT_MERGED, m.NAME])[1..10] ORDER BY r.WEIGHT_MERGED
我加入了orderbyr.WEIGHT\u MERGED
,作为如何再次按值排序的示例
如果您希望数据更结构化,还可以收集对象贴图,而不是像这样的数组:
MATCH (n) WHERE HAS(n.II_VAL)
WITH collect({n: n, II_VAL: n.`II_VAL`})[0..100] AS set1 ORDER BY n.`II_VAL` DESC
MATCH (n)-[r]->(m) WHERE HAS(m.VALUE)
RETURN set1, collect({n_name: n.NAME, weight_merged: r.WEIGHT_MERGED, m_name: m.NAME})[1..10] ORDER BY r.WEIGHT_MERGED
MATCH (n) WHERE HAS(n.II_VAL)
WITH n ORDER BY n.II_VAL DESC LIMIT 100
MATCH (n)-[r]->(m) WHERE HAS(m.VALUE)
WITH n, r, m ORDER BY m.VALUE DESC
RETURN n.NAME, COLLECT([r.WEIGHT_MERGED, m.NAME, m.VALUE])[0..10];
您只需要限制,然后继续查询。为了提供一个可复制的示例,让我们切换到Neo4j附带的电影数据集。假设你想抓取数据库中最老的3部电影,然后抓取其中每部电影中最老的2名演员
MATCH (m:Movie)
WITH m ORDER BY m.released LIMIT 3
MATCH (p:Person)-[:ACTED_IN]->(m)
WITH m, p ORDER BY p.born
WITH m, COLLECT(p.name)[0..2] AS oldest
RETURN m.title, oldest;
这将产生:
| m.title | oldest
---+---------------------------------+--------------------------------------
1 | Something's Gotta Give | ['Jack Nicholson', 'Diane Keaton']
2 | Top Gun | ['Tom Skerritt', 'Kelly McGillis']
3 | One Flew Over the Cuckoo's Nest | ['Jack Nicholson', 'Danny DeVito']
所以你会想要这样的东西:
MATCH (n) WHERE HAS(n.II_VAL)
WITH collect({n: n, II_VAL: n.`II_VAL`})[0..100] AS set1 ORDER BY n.`II_VAL` DESC
MATCH (n)-[r]->(m) WHERE HAS(m.VALUE)
RETURN set1, collect({n_name: n.NAME, weight_merged: r.WEIGHT_MERGED, m_name: m.NAME})[1..10] ORDER BY r.WEIGHT_MERGED
MATCH (n) WHERE HAS(n.II_VAL)
WITH n ORDER BY n.II_VAL DESC LIMIT 100
MATCH (n)-[r]->(m) WHERE HAS(m.VALUE)
WITH n, r, m ORDER BY m.VALUE DESC
RETURN n.NAME, COLLECT([r.WEIGHT_MERGED, m.NAME, m.VALUE])[0..10];
查询片段仅用于说明。请查看对我原始帖子的编辑。我没有使用循环。请查看对我的原始帖子的编辑。我需要合并这两个查询。请查看对我原始帖子的编辑。你可以将它们合并。关于您的编辑:您必须先排序
,然后收集()
仅返回要返回的关系或值。如果您希望再次拥有相同的节点顺序,您可能希望在返回中再次排序。是的,但我需要向从第一次排序搜索中获得的每个节点添加一个子查询(检索10个链接)。我不知道如何以一种非常简单的方式组合查询…好的,关闭:)但是,查询不知道第二行中的“n”(“n未定义”)(按n.II_VAL
排序)。如果我将它添加到“WITH”(WITH n,collect({n…)我将原来的排序按n.II_VAL
松开。但是它返回的内容的结构与我正在寻找的内容类似…将其从WITH
子句中删除,您正在失去绑定n
;此时,您只需在第3行的所有节点上进行匹配。这正是我需要的,谢谢。通过以下小的添加,我再次得到按n.II_VAL排序的最终列表:“…n,n.II_VAL为II,r,m按m.VALUE DESC排序返回n.NAME,II,COLLECT([r.WEIGHT_MERGED,m.NAME,m.VALUE])[0..2]按II DESC排序
MATCH (n) WHERE HAS(n.II_VAL)
WITH n ORDER BY n.II_VAL DESC LIMIT 100
MATCH (n)-[r]->(m) WHERE HAS(m.VALUE)
WITH n, r, m ORDER BY m.VALUE DESC
RETURN n.NAME, COLLECT([r.WEIGHT_MERGED, m.NAME, m.VALUE])[0..10];