类知乎网站的实现


图片.png

图片.png



查询问题列表:
ide

从这个方法返回的数据中能够看出,有一个answer_number字段, 即这个问题当前有多少个回答网站

1.先查询问题,再查询答案数量,这是最常想到的办法,代码以下:spa

        图片.png

    这种方法的优势是简单直接, 缺点是查询次数太多。假设有100 个问题,那么就须要查询101 次才能完成。这会致使网页加载数据显著下降。对象

2.使用$lookup 同时查询问题和回答图片

    在第8章中讲到了聚合操做的$lookup操做符。使用$lookup能够一次性查询两个集合。假设有100个问题,只须要查询1次,就能够同时得到全部的问题,以及它们各自对应的回答。使用聚合操做配合$lookup的代码以下:字符串

    图片.png

    图片.png

    图片.png



实现“查询回答”功能:it

进入一个问题的答案列表页之后,除看到答案外,还可以看到这个问题的描述。这说明在答案列表页面,不只要查询答案answer集合,还须要查询问题question集合。io

使用聚合查询的$lookup能够提升查询的效率,对应的代码以下:class

图片.png

图片.png

• 第2~8行:首先使用$match筛选出目标问题, 再根据目标问题对应的objectid查询问题和相应的回答, 井把回答存在名为answer_list的列表中。
• 第9行:聚合操做返回的结果是一个可法代的对象, 因为可迭代的对象的ID(Objectid)不重复,因此这里一定只有一个元素。所以把它转化为列表再取下标为0的元素。
• 第10~ 1 6 行:记录问题的信息。
• 第17 ~23 行:记录每一条回答的内容。
• 第24 行: 把回答的列表从新存入问题信息中。
修改好query_answer 方法后重启网站。在问题列表页中单击任何一个问题,则能够正常进入该问题的答案列表页面
效率


实现“提问与回答”功能:

提问对应MongoUtil类中的方法为insert_question,回答对应MongoUtil类中的方法为insert_answer,它们的代码以下:

图片.png

图片.png

这两个方法属于很是常规的数据插入操做。

在insert_answer方法中,参数question_id是问题对应的Objectld的字符串形式,须要首先将question_id转化为Objectld对象,再插入到MangoDB中


实现“点赞”与“点踩”劝能:

为问题“点赞”或“点睬” 对应MongoUtil类中的方法为vote_for_ question , 为答案“点赞”和“点踩”对应的方法名为vote_for_answer。它们都使用了MongoDB的update_one方法。

使用“$inc”操做符实现字段自增自减:

在MangoDB的基础部分中,update_one的用法为:

handler.update_one({"name":"xxx"},{"$set":{"age":12}})

意思是查询name字段值为xxx的记录,而后把这条记录的age字段更新为12

可是在这个项目中,“ 点赞”功能须要把字段vote_up 自增1,“ 点踩”功能须要把vote down字段自增l ,并且可能多个访客会同时对一个问题“点赞",因此“点赞”和“点踩”这两个操做都必须是原子操做,不能先查询当前问题的vote_ up是多少,而后再使用update_one来设置新的值。
为了实现原子操做的字段自增,就不能使用“$set”操做符而要改为“$inc”操做符。这个的inc对应了英文单词increase(增长)。

使用格式为:
    handler . update_one({"_id":问题或答案的Objectid},{"$inc":{"vote_up":1}})

实际上,自减就是在“$inc”的值对应的字典中把值设为负数。但因为本项目须要记录“点踩”的数量,因此把“点赞”和“点踩”分红两个字段来保存。所以不管是“点赞”仍是“点踩”都是自增操做。

2. 实现“点赞”和“点踩”
修改点赞和点踩的代码,实现它们的功能:

图片.png

须要注意的是,传入进来的value多是vote_up或者vote_down,所以把它直接做为$inc值字典的Key就能够自动实现赞或者踩。修改完成之后重启网站,能够看到“点赞”和“点踩”功能已经恢复正常。

相关文章
相关标签/搜索