類知乎網站的實現


圖片.png

圖片.png



查詢問題列表:

從這個方法返回的數據中可以看出,有一個answer_number字段, 即這個問題當前有多少個回答

1.先查詢問題,再查詢答案數量,這是最常想到的辦法,代碼如下:

        圖片.png

    這種方法的優點是簡單直接, 缺點是查詢次數太多。假設有100 個問題,那麼就需要查詢101 次才能完成。這會導致網頁加載數據顯著降低。

2.使用$lookup 同時查詢問題和回答

    在第8章中講到了聚合操作的$lookup操作符。使用$lookup可以一次性查詢兩個集合。假設有100個問題,只需要查詢1次,就可以同時獲得所有的問題,以及它們各自對應的回答。使用聚合操作配合$lookup的代碼如下:

    圖片.png

    圖片.png

    圖片.png



實現“查詢回答”功能:

進入一個問題的答案列表頁以後,除看到答案外,還能夠看到這個問題的描述。這說明在答案列表頁面,不僅要查詢答案answer集合,還需要查詢問題question集合。

使用聚合查詢的$lookup可以提高查詢的效率,對應的代碼如下:

圖片.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就可以自動實現贊或者踩。
修改完成以後重啓網站,可以看到“點贊”和“點踩”功能已經恢復正常。





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章