我正在尝试创建跨各种关系的事件提要。
到目前为止,我设法做到这一点的唯一方法是使用 UNION
运行 3 个语句。但是,您不能对所有联合的结果进行 LIMIT
和 ORDER
– 目前这似乎是 Neo 的一个限制。
有谁知道我如何重写下面的内容以便我可以订购和限制全部?
match (me:User {username:'bob'})-[:Owner]->(m:Message)<-[r:Likes|:Reply|:Share]-(u:User)
return m as message, u as user, lower(type(r)) as activity, r.created_on as date
order by date skip 0 limit 25
union match (me:User {username:'bob'})<-[r:Mentions]-(m:Message)-[:Owner]-(u:User)
return m as message, u as user, lower(type(r)) as activity, r.created_on as date
order by date skip 0 limit 25
union match (me:User {username:'bob'})<-[r:Follows]-(u:User)
return NULL as message, u as user, lower(type(r)) as activity, r.created_on as date
order by date skip 0 limit 25
我做到了这一点,它返回一个列,其中包含我需要的数据作为嵌套属性,但我不知道如何订购最终的集合......
match (me:User {username:'bob'})-[:Owner]->(m:Message)<-[r:Likes|:Reply|:Share]-(u:User)
with collect({activity:lower(type(r)), user:u, message:m, date:r.created_on}) as a1
optional match (me:User {username:'bob'})<-[r:Mentions]-(m:Message)-[:Owner]-(u:User)
with collect({activity:lower(type(r)), user:u, message:m, date:r.created_on }) as a2, a1
optional match (me:User {username:'bob'})<-[r:Follows]-(u:User)
with collect({activity:lower(type(r)), user:u, date:r.created_on }) as a3, a2, a1
with a3 + a2 +a1 as all
unwind all as activity
return activity
skip 0 limit 25
非常感谢任何帮助!
更新
所以现在我有了这个....
MATCH (me:User { username:'bob' })--(u:User)
OPTIONAL MATCH (me)-[:Owner]->(m:Message)<-[r:Likes|:Reply|:Share]-(u)
WITH me, collect({ type:lower(type(r)), user:u, message:m, date:r.created_on }) AS a1
OPTIONAL MATCH (me)<-[r:Mentions]-(m:Message)<-[:Owner]-(u)
WITH me, collect({ type:lower(type(r)), user:u, message:m, date:r.created_on }) AS a2, a1
OPTIONAL MATCH (me)<-[r:Follows]-(u)
WITH collect({ type:lower(type(r)), user:u, date:r.created_on })+ a2 + a1 AS all
UNWIND all AS activity
WITH activity
WHERE activity.type is not null
RETURN activity
ORDER BY activity.date
LIMIT 25;
有人能看出这有什么性能问题吗?
我在一开始就匹配我——用户,以确保我只寻找与我有某种关系的用户。然后在最后我从可选匹配中过滤掉 NUll 匹配。当我手动收集一个文字对象时,如果没有匹配项,它会得到一个包含 NULL 条目的对象,所以我只是在最后删除它们....
这一切都是因为你无法过滤 POST UNION!
最佳答案
尚不支持进行“后 UNION 处理”的能力,但 promise “尽快”(参见 neo4j issue 2725)。如果您希望尽快发生这种情况,您可能希望对该问题添加评论。
您尝试的解决方案很接近。这个查询应该工作得更好:
MATCH (me:User { username:'bob' })-[:Owner]->(m:Message)<-[r:Likes|:Reply|:Share]-(u:User)
WITH me, collect({ type:lower(type(r)), user:u, message:m, date:r.created_on }) AS a1
OPTIONAL MATCH (me)<-[r:Mentions]-(m:Message)<-[:Owner]-(u:User)
WITH me, collect({ type:lower(type(r)), user:u, message:m, date:r.created_on }) AS a2, a1
OPTIONAL MATCH (me)<-[r:Follows]-(u:User)
WITH collect({ type:lower(type(r)), user:u, date:r.created_on })+ a2 + a1 AS all
UNWIND all AS activity
RETURN activity
ORDER BY activity.date
LIMIT 25;
这个查询:
ORDERS BY
组合事件的日期,以便返回最早的 25 个事件。这是您的查询所需的主要更改。- 消除不需要的
SKIP 0
子句。 - 通过前 2 个
WITH
子句传递me
,这样OPTIONAL MATCH
子句就不必重新查找me
再次。
关于Neo4j : how to implement SKIP and LIMIT on a UNION cypher ? 有哪些替代方案?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33071037/