这是场景。我正在尝试创建用户之间最近(多个消息)对话的收件箱,其中最新消息(已发送或已接收)在列表中有简短预览。
(顺便说一下,我知道发布的UNION过滤问题是开放的:https://github.com/neo4j/neo4j/issues/2725),但我不确定我的问题是否得到了完全的回答。
让我们假设它显示如下:
用户1的收件箱:
user03 - “嘿,我要......”
user02 - “哟用户2,我看到了......”
user04 - “你知道我有没有......”
user26 - “亲爱的user01我只是......”
在图表数据库中,对话用以下关系表示:
(:User)<-[s:SENDER]-(m:Message)-[r:RECEIVER]->(:User)
匹配这个并通过m.created_at排序可以获得对话。
我可以轻松找到特定用户之间的消息,我可以轻松找到包含给定用户的所有消息,例如在以下查询中(给定用户名为“brendanh”:
MATCH (u:User)<-[s:SENDER]-(m:Message)-[r:RECEIVER]->(u2:User)
WHERE (u.username = "brendanh") OR (u2.username = "brendanh")
RETURN m.body, u.username as sender, u2.username as receiver ORDER BY m.created_at DESC
显然,之前的查询从“brendanh”
获取了所有消息示例结果行:
body sender receiver
blah blah blah brendanh user2
foo foo foo user3 brendanh
bar bar bar user2 brendanh
test test brendanh user4
i do not know user3 brendan
我想要的是:
body sender receiver
blah blah blah brendanh user2
foo foo foo user3 brendanh
test test brendanh user4
我可以通过以下方式获得 一组独特的会话参与者:
MATCH (u:User {username:'brendanh'})<-[]-(m:Message)-[]->(u2:User)
return distinct(u2.username)
但这并不像我可以获取单个用户名列表并在其上执行“For”匹配,返回每个用户名的第一个消息匹配。 (在我所说的密码查询中)
我可以收集会话参与者列表(我在Golang中运行它),然后针对每个单独的结果运行对graphdb的查询,但这看起来很混乱。
我尝试过使用UNWIND和前面描述的查询中列出会话伙伴的用户名列表,但我再次得到的每条消息不仅仅是每个用户的第一条消息。
这里有什么非常明显的东西吗?
感谢任何帮助,谢谢!
P.S。理想情况下,我想限制响应的数量,这样如果我只想显示前十个结果,假设用户有> 10个对话但不太重要
答案 0 :(得分:0)
不太容易理解你想要什么,但我想我明白了。
您希望每个合作伙伴只能在列表中出现一次吗?消息。
也许是这样:
MATCH (u:User)<-[r:SENDER|:RECEIVER]-(m:Message)-[:SENDER|:RECEIVER]->(u2:User)
WHERE (u.username = "brendanh")
WITH u2,m,type(r) as action ORDER BY m.created_at DESC
WITH u2,head(collect({type:type(r), msg: m})) as conv
RETURN u2.username, conv.msg.body, conv.type