Graph Neo4j-如何为我的图构建适当的多维查询

Graph Neo4j-如何为我的图构建适当的多维查询,graph,neo4j,cypher,Graph,Neo4j,Cypher,我有一个简单的社交网络,比如图,包括用户、朋友、评论、喜欢等。用户可以“拥有”项目,评论“项目”,比如“项目”。我正在尝试编写一个密码查询,返回“items”以及额外的信息,以便在我的流中显示它们 我已经尝试过使用可选匹配和收集之类的东西,但结果中总会有部分不起作用 具体来说,对于给定的用户(比如user1),我想返回“items”: 特定用户+他自己的朋友 显示喜欢的数量 同时显示评论的数量 知道该项目是否已归我所有(以便我可以在UI中隐藏“own”按钮) 如果该项目是由朋友拥有的,我想显示最

我有一个简单的社交网络,比如图,包括用户、朋友、评论、喜欢等。用户可以“拥有”项目,评论“项目”,比如“项目”。我正在尝试编写一个密码查询,返回“items”以及额外的信息,以便在我的流中显示它们

我已经尝试过使用可选匹配收集之类的东西,但结果中总会有部分不起作用

具体来说,对于给定的用户(比如user1),我想返回“items”:

  • 特定用户+他自己的朋友
  • 显示喜欢的数量
  • 同时显示评论的数量
  • 知道该项目是否已归我所有(以便我可以在UI中隐藏“own”按钮)
  • 如果该项目是由朋友拥有的,我想显示最多2个朋友的姓名、图像(但如果有5个朋友拥有该项目,则不超过2个朋友)
  • 您可以复制下面的“粘贴”以获取图形

    // 3 users
    CREATE (u1:USER{name:"USER1", image: "image1"})
    CREATE (u2:USER{name:"USER2", image: "image2"})
    CREATE (u3:USER{name:"USER3", image: "image3"})
    
    //3 items
    CREATE (i1:ITEM{name:"ITEM1"})
    CREATE (i2:ITEM{name:"ITEM2"})
    CREATE (i3:ITEM{name:"ITEM3"})
    
    
    // OWNERSHIP ..
    
    //user1 owns 2 items
    CREATE (u1)-[:OWNS]->(i1)
    CREATE (u1)-[:OWNS]->(i2)
    
    
    // user2 owns i2 and i3 
    CREATE (u2)-[:OWNS]->(i2)
    CREATE (u2)-[:OWNS]->(i3)
    
    // user3 also owns i2 and i3 (so i2 is owned by u1, u2 and u3; and i3 is owned by u2 and u3)
    CREATE (u3)-[:OWNS]->(i2)
    CREATE (u3)-[:OWNS]->(i3)     
    
    // FRIENDSHIP..
    
    // user1 is friend of both user2 and user3
    CREATE (u1)-[:FRIEND_OF]->(u2)
    CREATE (u1)-[:FRIEND_OF]->(u3)
    
    
    // COMMENTS ..
    
    //user1 has commented on all those items he owns
    CREATE (u1i1:COMMENT{text:"user1 comment on item1"})
    CREATE (u1)-[:COMMENTED]->(u1i1)-[:COMMENT_FOR]->(i1)
    
    CREATE (u1i2:COMMENT{text:"user1 comment on item2"})
    CREATE (u1)-[:COMMENTED]->(u1i2)-[:COMMENT_FOR]->(i2)
    
    //user 2 has also commented on all those he owns
    CREATE (u2i2:COMMENT{text:"user2 comment on item2"})
    CREATE (u2)-[:COMMENTED]->(u2i2)-[:COMMENT_FOR]->(i2)
    
    CREATE (u2i3:COMMENT{text:"user2 comment on item3"})
    CREATE (u2)-[:COMMENTED]->(u2i3)-[:COMMENT_FOR]->(i3)
    
    
    // LIKES ..
    
    //user1 has liked user2's and user3's items
    CREATE (u1)-[:LIKED]->(i2)
    CREATE (u1)-[:LIKED]->(i3)
    
    //user2 has liked user1's items
    CREATE (u2)-[:LIKED]->(i1)
    

    相当容易。首先,您需要在的
    FRIEND\u上有一个从0..1开始的可变路径长度匹配,并返回您自己。跟踪那些人拥有的所有物品

    使用
    可选匹配
    查找喜欢和评论,因为可能存在也可能不存在

    由于单个项目可能有多个路径,因此需要计算不同的喜欢和评论

    若要检查您是否已经拥有该项,请从上面检查变量路径匹配的端点(如果其名称是您的)

    要获取最多两张拥有该项目的朋友的图像,请筛选朋友列表并返回
    图像
    属性。最后一步是使用下标运算符对前两个元素的集合进行切片

    MATCH (:USER { name:'USER1' })-[:FRIEND_OF*0..1]->(me_or_friend)-[:OWNS]->(item)
    OPTIONAL MATCH (item)<-[l:LIKED]-()
    OPTIONAL MATCH (item)<-[c:COMMENT_FOR]-()
    WITH item, count(distinct l) AS likes, count(distinct c) AS comments, 
        collect(DISTINCT me_or_friend) AS me_or_friends
    RETURN item, likes, comments, 
        ANY (x IN me_or_friends WHERE x.name='USER1') AS i_already_own,
        [x IN me_or_friends  WHERE x.name<>'USER1' | x.image][0..2] as friendImages
    
    匹配(:USER{name:'USER1})-[:FRIEND\u OF*0..1]->(me\u或\u FRIEND)-[:OWNS]->(项目)
    
    可选匹配(项)让我们逐步建立您的查询:

    具体来说,对于给定的用户(比如user1),我想返回“items”: 特定用户+他自己的朋友

    MATCH (u:USER {name: "USER1"})-[:FRIEND_OF*0..1]-(friend:USER)-[:OWNS]-(i:ITEM)
    WITH u,i, 
         // Know if the item is already owned by me (so I can hide "own" button in the UI) 
         sum(size((u)-[:OWNS]->(i))) > 0 as user_owns,
         // If the item is owned by friends, I want to show name, image of up to 2 friends 
         collect({name:friend.name, image:friend.image})[0..2] as friends
    
    RETURN u,i, user_owns, friends
    // show number of likes,
           sum(size(()-[:LIKED]->(i))) as like,
    // also show number of comments,
           sum(size(()-[:COMMENT_FOR]->(i))) as comments
    

    事实上,因为这是一个非常好的问题,我坐下来创建了一个。

    谢谢@stefan。抱歉,我忘记添加我正在使用的查询。前3行与你的相同,但我没有使用“with”,也根本不知道下标。。。太不可能了,谢谢迈克尔!那个画师真的很酷,也很有帮助!我甚至都不知道。从你和stephan的答案中学到了很多。