首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何考虑Neo4j新闻提要中的共享帖子?

如何考虑Neo4j新闻提要中的共享帖子?
EN

Stack Overflow用户
提问于 2016-10-25 23:42:59
回答 2查看 213关注 0票数 1

我已经为特定的POSTS节点的每个FRIEND链接了与NEXT关系相连接的USER列表:

USER->:STATUS->POST->:NEXT->POST->:NEXT->POST->:NEXT->POST

我可以从用户朋友那里检索最近的15篇文章,如下所示:

代码语言:javascript
复制
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的共享。为了保持提要检索的简单性,我们在一定程度上进行了反错,并将共享帖子的post_id存储在这些链接列表中的新POST上。

因此,用户朋友偶尔会共享相同的帖子,从而导致返回的几个statusupdates具有相同的share id/属性。这样的结果会在应用程序级别进行聚合(John、Jane和Sarah共享这篇文章)

但这当然意味着,有时检索15个结果会导致not生成15个实际的新闻提要项目。因为有几个项目最终被聚合成一个。

我的第一反应是确保上面查询中的LIMIT子句通过结果集中找到的共享属性的数量来增加,这样当有足够的可用时,我们仍然有15个单独的新闻提要项(affter级聚合)。

例如:

如果有4个帖子都具有相同的share id,另有2个带有另一个share id的帖子和所有rest都没有共享属性,那么我们需要向LIMIT子句中添加(4+2)或6。

不幸的是,似乎LIMIT子句不能使用变量,因此简单地计算share属性的出现并增加LIMIT是不可行的。

我怎么才能最好地处理这件事?

Neo4J可以在限制结果之前进行这种聚合吗?如果是这样的话,是怎么做的?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-10-26 00:25:44

您可能需要考虑一个:起源关系,从任何共享的帖子到原来的帖子。这可以让您对原始帖子执行聚合,并收集那些共享/发布这些帖子的朋友。这样的东西(还没有测试过):

代码语言:javascript
复制
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

如果它是一个朋友的原始帖子,来源将是相同的地位(没有起源关系,因此该状态本身作为原产地返回),只有一个朋友将在收集中。

如果这是一个由几个朋友分享的帖子,来源将是原始的帖子,朋友收集将包括所有分享该帖子的朋友。

如果一位朋友发了原件,另一位朋友分享了原稿,那么了解发原件的人是有用的。这可以很容易地添加到查询中,或者只需返回原始的海报id,并在应用程序层中查找匹配的内容。

票数 1
EN

Stack Overflow用户

发布于 2016-10-26 01:20:46

这似乎能做你想做的事:

代码语言:javascript
复制
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,它就会将每个update/myfriend对添加到res集合中;在达到最大大小之后,它将保持集合不变。

请注意,原始查询中的[rels:FRIEND*0..1]语法还将返回me的帖子,这似乎不符合您所说的要求。如果你真的只想要朋友的帖子,就像我在查询中所做的那样,用[rels:FRIEND]代替。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40251487

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档