类知乎网站的实现


类知乎网站的实现

类知乎网站的实现



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

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

类知乎网站的实现

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

2。使用查找同美元时查询问题和回答

在第8章中讲到了聚合操作的美元查找操作符。使用美元查找可以一次性查询两个集合。假设有100个问题,只需要查询1次,就可以同时获得所有的问题,以及它们各自对应的回答。使用聚合操作配合美元查找的代码如下:

类知乎网站的实现

类知乎网站的实现

类知乎网站的实现



进入一个问题的答案列表页以后,除看到答案外,还能够看到这个问题的描述。这说明在答案列表页面,不仅要查询答案回答集合,还需要查询问题问题集合。

使用聚合查询的美元查找可以提高查询的效率,对应的代码如下:

类知乎网站的实现

类知乎网站的实现

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


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

类知乎网站的实现

类知乎网站的实现

这两个方法属于非常常规的数据插入操作。

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


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

使用“美元公司”操作符实现字段自增自减:

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

handler.update_one ({" name ": " xxx "},{" $集":{“年龄”:12}})

意思是查询名称字段值为xxx的记录,然后把这条记录的年龄字段更新为12

但是在这个项目中,“点赞“功能需要把字段vote_up自增1,点“踩”功能需要把否决字段自增l,而且可能多个访客会同时对一个问题“点赞”,所以“点赞”和“点踩”这两个操作都必须是原子操作,不能先查询当前问题的vote_起来是多少,然后再使用update_one来设置新的值。
为了实现原子操作的字段自增,就不能使用“设置美元”操作符而要改成“美元公司”操作符。这个的公司对应了英文单词增加(增加)。

使用格式为:
处理程序。update_one ({" _id ":问题或答案的Objectid},{“美元公司”:{“vote_up”: 1}})

实际上,自减就是在“美元公司”的值对应的字典中把值设为负数。但由于本项目需要记录”点踩”的数量,所以把“点赞”和“点踩”分成两个字段来保存。因此无论是“点赞”还是“点踩”都是自增操作。

类知乎网站的实现