查詢問題列表:
ide
從這個方法返回的數據中能夠看出,有一個answer_number字段, 即這個問題當前有多少個回答網站
1.先查詢問題,再查詢答案數量,這是最常想到的辦法,代碼以下:spa
這種方法的優勢是簡單直接, 缺點是查詢次數太多。假設有100 個問題,那麼就須要查詢101 次才能完成。這會致使網頁加載數據顯著下降。對象
2.使用$lookup 同時查詢問題和回答圖片
在第8章中講到了聚合操做的$lookup操做符。使用$lookup能夠一次性查詢兩個集合。假設有100個問題,只須要查詢1次,就能夠同時得到全部的問題,以及它們各自對應的回答。使用聚合操做配合$lookup的代碼以下:字符串
實現「查詢回答」功能:it
進入一個問題的答案列表頁之後,除看到答案外,還可以看到這個問題的描述。這說明在答案列表頁面,不只要查詢答案answer集合,還須要查詢問題question集合。io
使用聚合查詢的$lookup能夠提升查詢的效率,對應的代碼以下:class
• 第2~8行:首先使用$match篩選出目標問題, 再根據目標問題對應的objectid查詢問題和相應的回答, 井把回答存在名爲answer_list的列表中。
• 第9行:聚合操做返回的結果是一個可法代的對象, 因爲可迭代的對象的ID(Objectid)不重複,因此這裏一定只有一個元素。所以把它轉化爲列表再取下標爲0的元素。
• 第10~ 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_ 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. 實現「點贊」和「點踩」
修改點贊和點踩的代碼,實現它們的功能:
須要注意的是,傳入進來的value多是vote_up或者vote_down,所以把它直接做爲$inc值字典的Key就能夠自動實現贊或者踩。修改完成之後重啓網站,能夠看到「點贊」和「點踩」功能已經恢復正常。