我为特定POSTS
NODE的每个NEXT
链接了与FRIEND
关联的USER
列表:
USER-> [:STATUS] - > POST-> [:NEXT] - > POST-> [:NEXT] - > POST-> [:NEXT] - > POST
我可以从用户朋友那里检索最近的15个帖子,如下:
MATCH (me:USER { userid: 'John.Smith' })-[rels:FRIEND*0..1]-(myfriend)
MATCH (myfriend)-[:STATUS]-(latestupdate)-[:NEXT*0..15]-(statusupdates)
RETURN statusupdates, myfriend
ORDER BY statusupdates.time DESC SKIP 0 LIMIT 15
现在,其中一些帖子可能会'是存储在图表中其他位置的其他POSTS
的份额。为了简化Feed检索,我们进行了一些非规范化处理,并将共享帖子的post_id
存储在这些链接列表中的新POST
上。
因此,有时用户朋友会分享相同的帖子,导致多个返回的statusupdates
具有相同的share
id /属性。这些结果在应用程序级别汇总(John,Jane和Sarah分享了这篇文章)
但这当然意味着有时检索15个结果not
会导致15个实际新闻源项目。由于有几个项目最终汇总为一个。
我的第一直觉是简单地确保上述查询中的LIMIT
子句增加了结果集中找到的共享属性的数量,这样我们最终仍会得到15个单独的新闻源项目(更多)应用程序级别聚合)当足够可用时。
例如:
如果我们有4个帖子都具有相同的share
ID,另有2个帖子带有另一个share
ID,而其他所有帖子都没有共享属性,那么我们需要添加add(4+) 2)或6到LIMIT
条款。
不幸的是,似乎LIMIT
子句不能使用变量,所以简单地计算share
属性的出现次数并增加LIMIT
是不行的。
我怎样才能最好地处理这个问题?
在限制结果之前,Neo4J可以进行这种聚合吗?如果是这样,怎么样?
答案 0 :(得分:1)
您可能需要考虑从任何共享帖子到原始帖子的[:ORIGIN]关系。这可以让您对原始帖子进行聚合,并收集共享/发布它们的朋友。这样的事情(尚未测试):
MATCH (me:USER { userid: 'John.Smith' })-[rels:FRIEND*0..1]-(myfriend)
MATCH (myfriend)-[:STATUS]-(latestupdate)-[:NEXT*0..15]-(statusupdates)-[:ORIGIN*0..1]->(origin)
RETURN origin, COLLECT(myFriend) as friends, MAX(statusupdates.time) as time
ORDER BY time DESC SKIP 0 LIMIT 15
如果它是朋友的原始帖子,则origin将与statusupdate相同(没有原始关系,因此statusupdate本身将作为原点返回),并且只有一个朋友将在该集合中。
如果是几个朋友分享的帖子,原点将是原始帖子,好友集合将包括分享帖子的所有朋友。
如果一位朋友发布了原文,而另一位朋友分享了原文,那么了解发布原文的人将会很有用。这是您可以轻松添加到查询中的内容,或者您只需返回原始海报ID并在应用程序层中查找该匹配项。
答案 1 :(得分:1)
这似乎可以做你想要的:
MATCH (me:USER { userid: 'John.Smith' })-[rels:FRIEND]-(myfriend)
MATCH (myfriend)-[:STATUS|NEXT*..16]-(statusupdates)
WITH statusupdates, myfriend
ORDER BY statusupdates.time DESC
WITH REDUCE(s = {ids:[], res:[]}, x IN COLLECT({statusupdates: statusupdates, myfriend: myfriend}) |
CASE
WHEN SIZE(s.ids) < 15 THEN
CASE
WHEN x.statusupdates.post_id IS NULL THEN
CASE
WHEN x.statusupdates.id IN s.ids THEN
{ids: s.ids, res: s.res + x}
ELSE {ids: s.ids + x.statusupdates.id, res: s.res + x}
END
WHEN x.statusupdates.post_id IN s.ids THEN
{ids: s.ids, res: s.res + x}
ELSE {ids: s.ids + x.statusupdates.post_id, res: s.res + x}
END
ELSE s
END) AS out
UNWIND out.res AS result
RETURN result;
逻辑返回最多15个唯一更新ID,允许多次引用相同的id。它假定所有更新都具有唯一的id
属性和引用另一个更新的可选post_id
属性。 REDUCE
子句只会在id
集合中放置更新ids
,如果它没有post_id
属性(并且它不在集合中),否则它将post_id
值放入集合中(如果它尚未存在)。只要ids
集合的大小小于15,它就会将每个更新/我的朋友对添加到res
集合中;达到最大尺寸后,它将保持收藏不变。
请注意,原始查询中的[rels:FRIEND*0..1]
语法也会按me
返回帖子,这似乎与您所说的内容不符。如果你真的想要朋友的帖子,请改用[rels:FRIEND]
,就像我在查询中所做的那样。