V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
WildCat
V2EX  ›  问与答

V2EX 的忽略主题,屏蔽人的功能,在查询帖子列表的时候是如何实现的?

  •  
  •   WildCat · 2014-11-25 11:15:33 +08:00 via iPhone · 2366 次点击
    这是一个创建于 3449 天前的主题,其中的信息可能已经有所发展或是发生改变。
    最近在用rails写一个小社区,也是打算实现忽略主题和Block的功能。那么问题来了:
    如果用户屏蔽了某几个主题和用户,查询的时候只能用几个 where topic.id != [blocked_id] 实现吗?如果想缓存和分页,有什么好办法吗?
    我是想把帖子列表的内容缓存30秒,不过每个用户屏蔽的内容不同,只有分别做了吗?
    12 条回复    2014-11-25 17:22:15 +08:00
    barbery
        1
    barbery  
       2014-11-25 11:20:20 +08:00
    屏蔽的id写在redis里,输出的时候判断下就可以了
    if(articleId not in $blockList)
    echo $content
    xoxo
        2
    xoxo  
       2014-11-25 11:21:35 +08:00
    SQL:

    ```SQL
    authorId NOT IN(....)
    ```
    WildCat
        3
    WildCat  
    OP
       2014-11-25 12:05:12 +08:00 via iPhone
    @barbery 这样不行,比如每页10个,去掉屏蔽的只有8个了


    @xoxo …这是目前能想到的做法了
    panxianhai
        4
    panxianhai  
       2014-11-25 12:39:52 +08:00
    @xoxo 屏蔽了一大波人的话会不会有效率问题?
    lichao
        5
    lichao  
       2014-11-25 12:44:55 +08:00   ❤️ 1
    @WildCat 用个 not in 可以,并不会 [每页10个,去掉屏蔽的只有8个] ,而是去掉了之后才分页的,所以每页帖数仍然不变
    lichao
        6
    lichao  
       2014-11-25 12:48:42 +08:00   ❤️ 1
    @WildCat v2ex 的忽略功能,应该是通过前端 js 来隐藏的

    https://gist.github.com/anonymous/2d595e96bf91de5b5102

    这样反而会出现像你说的 [每页10个,去掉屏蔽的只有8个了]
    xoxo
        7
    xoxo  
       2014-11-25 13:15:15 +08:00
    @panxianhai authorId加索引
    dingyaguang117
        8
    dingyaguang117  
       2014-11-25 13:28:27 +08:00
    @xoxo 如果忽略的很多,效率很成问题吧
    raincious
        9
    raincious  
       2014-11-25 13:55:02 +08:00   ❤️ 1
    仔细想了下,好难啊。

    是啊,着么简单的功能,用个NOT IN就可以了。但是自从给自己定了规矩不允许使用JOIN和子查询之后,很多东西都需要重新思考。

    这个问题其实还是要减少数据查询量的问题。逻辑就比较复杂了。

    假定你的数据库里有1亿条帖子,你当前用户屏蔽了1亿用户。列表页需要输出100个帖子项目。那么这样做可能最经济:

    1、查询所有帖子,但不是100个,而是比100大的数字,比如110个,用得到的“帖子列表”数据组成“发帖者列表”和“帖子编号列表”(注意要处理分页编号);
    2、去除重复的发帖者(帖子编号不可能重的=)),这样“发帖者列表”和“帖子编号列表”里面的总数是可控的,最大110个项;
    3、用这110个数据项去查询“用户屏蔽的帖子”以及“用户屏蔽的用户”表,用IN。得到数据之后过滤已有的“帖子列表”。

    这样数据库最多取出330个数据项,比NOT IN节省很多,因为直接NOT IN数据库那边可能会比较忙(但貌似IN自己也有索引问题?没有仔细研究过,求教)。

    取110是为了给过滤留下容差,这样能让用户的列表尽量满100项。如果实在不满,你可以从上面第1步开始再发出一组查询,直到填满100项(不建议)。

    110也可以根据用户当前屏蔽的数量动态判断。当然,肯定不会很准确,无法完全保证帖子列表一次取完。
    panxianhai
        10
    panxianhai  
       2014-11-25 14:43:36 +08:00   ❤️ 1
    刚才在首页和列表页屏蔽了几个用户看了一下,缓存的数据应该是一样的,根据不同的用户访问然后过滤掉屏蔽的用户再显示出来。
    屏蔽前41条数据,屏蔽了之后40条数据,说明不再补充数据了。
    问与答列表第一页,分也应该是20一页,屏蔽之后,第一页19条数据,第二页20条数据。

    我想应该是每个用户缓存屏蔽,忽略等列表,不同的用户针对这个列表进行过滤。
    Livid
        11
    Livid  
    MOD
       2014-11-25 14:45:03 +08:00   ❤️ 1
    让数据库做的事情越简单越好。
    dorentus
        12
    dorentus  
       2014-11-25 17:22:15 +08:00
    “每页10个,去掉屏蔽的只有8个了”其实也还算可以接受吧。

    我屏蔽了五百多人、五十个节点,于是还偶尔能看到空的首页呢……
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5965 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 01:55 · PVG 09:55 · LAX 18:55 · JFK 21:55
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.