【问题标题】:How to order by the result of combining multiple collect?如何按组合多个collect的结果排序?
【发布时间】:2014-03-06 05:54:59
【问题描述】:

我有一个这样的查询:

MATCH (a)-[:Shout]->(b)
WHERE a.user_id=1
WITH b.post_id as b_post_id, a, b.post as b_post
MATCH (a)-[:Friend]->(c)-[:Shout]->(d)
WITH d.post_id as d_post_id, b_post_id, d.post as d_post, b_post
order by d_post_id desc, b_post_id desc
RETURN collect(distinct d_post) + collect(distinct b_post) as p

我想返回来自用户和朋友的所有帖子,所以我将 2 匹配 第一个匹配 (a)-[:Shout]->(b) 将返回用户的帖子,第二个匹配 (a)-[:Friend]->(c)-[:Shout]->(d) 将返回来自朋友的帖子。

(a)-[:Shout]->(b)的帖子是

post_id: 5, post: nana
post_id: 2, post: hi

(a)-[:Friend]->(c)-[:Shout]->(d)的帖子是

post_id: 6, post: lala
post_id: 4, post: hello
post_id: 3, post: hanson

所以,当我RETURN collect(distinct d_post) + collect(distinct b_post) as p 时,它将是 P: nana, hi, lala, hello, hanson

应该是:lala, nana, hello, hanson, hi6,5,4,3,2

请帮助我。 谢谢。

【问题讨论】:

    标签: neo4j sql-order-by match cypher collect


    【解决方案1】:

    怎么样

    MATCH (a {user_id:1})-[:Friend*0..1]->()-[:Shout]->(b)
    WITH b.post_id as post_id, b.post as post ORDER BY post_id desc
    RETURN collect(post) as posts
    

    编辑

    根据评论,如果您想返回 -[:Shout]->(b) 的节点的 id,您可以为可选的朋友位置添加标识符

    MATCH (a {user_id:1})-[:Friend*0..1]->(friendOrUser)-[:Shout]->(b)
    WITH friendOrUser, b ORDER BY b.post_id desc
    RETURN friendOrUser.user_id, b.post
    

    这里friendOrUser 绑定了用户a 和他的朋友。

    【讨论】:

    • 它有效,但我忘了告诉我不仅要返回帖子。我看到您的代码可以很好地返回帖子,但是当我尝试返回用户名和朋友时,它只返回您在查询中声明的具有 user_id:1 的用户。
    • (a {user_id:1})-[:Friend*0..1]->()-[:Shout]->(b) 不是表示用户和自己的朋友吗?
    • 不,这意味着匹配来自a和a的朋友的所有呼喊。使用a 的限制属性,它将始终是那个单独的节点,但未绑定的节点位置[:Friend*0..1]->() 可以同时保存a 和a 的朋友(在从a 到a 的零传出[:Friend] 之后)。给那个地方一个标识符并返回它的值以获取用户和用户朋友的 id。在这里,我将更新我的答案。
    • 是的,我已经这么想了。所以 (a {user_id:1})-[:Friend*0..1]->()-[:Shout]->(b)(a {user_id:1})-[:Friend]->()-[:Shout]->(b) 不同?起初我使用(a {user_id:1})-[:Friend]->()-[:Shout]->(b),但我应该让用户与自己成为朋友,但在我想知道什么用户与自己成为朋友之后,我在stackoverflow上问了它,我得到了解决方案,我只知道关系可以像@ 987654333@ 非常感谢。真的很有帮助。
    • 我需要你的建议。在RETURN 之前或RETURN 之后使用ORDER BY 哪个更好?在RETURN 之前就像:MATCH (a {user_id:1})-[:Friend*0..1]->(friendOrUser)-[:Shout]->(b) WITH friendOrUser, b ORDER BY b.post_id desc RETURN friendOrUser.username, b.post 或在RETURN 之后就像:MATCH (a {user_id:1})-[:Friend*0..1]->(friendOrUser)-[:Shout]->(b) RETURN friendOrUser.username, b.post ORDER BY b.post_id desc 或者它们都一样?
    【解决方案2】:

    试试下面。查询不是很干净,但可以完成这项工作。

    MATCH (a)-[:Shout]->(b)
    WHERE a.user_id=1
    WITH b,a
    MATCH (a)-[:Friend]->(c)-[:Shout]->(d)
    WITH b,d
    MATCH (dummy) WHERE (dummy = b OR dummy = d) 
    WITH dummy ORDER BY dummy.post_id DESC
    RETURN collect(distinct dummy.post) AS p
    

    【讨论】:

    • 它有效,但我认为它效率不高,那么有什么方法可以解决这个问题吗?还是使用 UNION 比 COLLECT 更好?
    • 根据我的理解,目前无法对两个集合的聚合进行排序。你可以去联合,但上面的查询比联合更好......你可以尝试和测试......无论如何,它们的逻辑都是相同的,以列形式呈现所有节点属性,然后对其进行排序,因为 ORDER BY 只接受属性节点或关系
    • 我知道上面的查询比 UNION 好,但在某些情况下仍然无法正常工作,例如当我将 user_id 更改为 2 或其他时,它不返回任何帖子,当我尝试返回发布它的用户时,它只返回用户。它应该能够返回用户和用户朋友的朋友。
    • 如果它适用于 user_id = 1,它应该适用于 user_id=2,请检查数据...请发布您正在尝试的查询..如果可能,请发布图表要点..
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-14
    • 1970-01-01
    • 2012-06-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多