我在一个看似简单的查询中失败了。
ALGO:
按某个值(desc)对节点排序:
MATCH (n) WHERE has(n.II_VAL) WITH n, n.II_VAL as ShInflInd order by ShInflInd desc
对于每个节点,返回其直接邻居(按第二个值排序):
MATCH (n)-[r]->(m) with n, m, m.VALUE as SubsOpRev order by SubsOpRev desc
挑战是返回前100个节点,并且每个节点只返回10个关系r(如果可能的话,在一行中)。
修改
很抱歉,因此人们对我的理解不正确。
详细地说,以下查询为我提供了顶级节点,排序:
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或SubsOpRev排序)后,查询返回第二个节点(“BARCLAYS 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], ...
这意味着我仍然坚持使用“PUBLIC”。
稍微修改查询会使事情变得更糟,因为它会返回完全不同的数据:
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], ... |
答案 0 :(得分:2)
您只需要限制然后继续查询。为了提供可重现的示例,让我们切换到Neo4j附带的电影数据集。让我们假设您想要抓住数据库中最古老的3部电影,然后再拍摄每部电影中最老的两部演员。
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 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];
答案 1 :(得分:1)
你能描述一下这个问题是什么吗?
最大的问题似乎是您没有使用RETURN
完成查询。 WITH
用于中间传递数据。此外,您实际上并不需要提取值来对其进行排序。你可以这样做:
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
编辑:抱歉,忘了LIMIT
答案 2 :(得分:1)
您可以将节点数限制为100:
MATCH (n)
WHERE has(n.II_VAL)
WITH n, n.II_VAL AS ShInflInd
ORDER BY ShInflInd DESC
LIMIT 100
您可以收集所有SubsOpRev
,然后RETURN
一部分收藏品。这一行(我假设SubsOpRev
是你想要的):
MATCH (n)-[r]->(m)
WITH n, m.VALUE AS SubsOpRev
ORDER BY SubsOpRev DESC
RETURN n, collect(DISTINCT SubsOpRev)[1..10]
这将为您提供每行一个节点n
以及所有收集的SubsOpRev
列表的一部分。
答案 3 :(得分:0)
要根据您的第一个查询获取前100个节点,您必须在订单后添加RETURN
子句和LIMIT
子句:
MATCH (n)
WHERE has(n.II_VAL)
RETURN n, n.II_VAL as ShInflInd
order by ShInflInd desc
LIMIT 100
对于第二个,您必须执行两个查询,并在客户端实现Foreach逻辑。因为您不能为第一个限制为100,然后为同一个查询中的每个节点获取10个相关节点。
答案 4 :(得分:0)
我认为您所说的是您希望在一个查询中返回两组结果。要做到这一点,我认为最好的办法是collect
中的WITH
,它只会给你一行,然后RETURN
这个值和collect
其他数据。类似的东西:
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
我投入ORDER BY r.WEIGHT_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