溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

教你如何用 MongoDB 實(shí)現(xiàn)評(píng)論榜功能

發(fā)布時(shí)間:2020-08-17 01:36:18 來(lái)源:網(wǎng)絡(luò) 閱讀:287 作者:艾弗森哇 欄目:數(shù)據(jù)庫(kù)
Mongodb很適合做這件事,api的調(diào)用僅僅是使用到了入門(mén)級(jí)別的CRUD,理清楚了思路,編碼也會(huì)順風(fēng)順?biāo)?所以你會(huì)發(fā)現(xiàn)我在這篇博客中說(shuō)的比編碼還多。

評(píng)論榜預(yù)期的功能

就像是StackOverFlow的那樣, 用戶可以發(fā)出自己的提問(wèn),其他用戶來(lái)解答, 同時(shí)樓主可以回復(fù)別人的評(píng)論,別人依然可以回復(fù)樓主

數(shù)據(jù)結(jié)構(gòu)

mongodb可以存儲(chǔ)文檔啊, 其實(shí)我們要做的就是構(gòu)建一個(gè)合適的類(lèi),評(píng)論幫也就成功一大半了

問(wèn)題/ 評(píng)論 實(shí)體如下

問(wèn)題

public?class?Problem?implements?Serializable?{
@Id
private?String?_id;//?key
private?String?nickname;?//?用戶名
private?String?avator;?//?用戶頭像
private?String?userId;?//?戶名id
private?String?title?;?//?標(biāo)題
private?String?content?;??//?內(nèi)容
private?boolean?answered?;?//?是否已經(jīng)回答
private?Date?createTime?;?//?創(chuàng)建時(shí)間
private?boolean?flag?=false;?//?標(biāo)記是否是本人,默認(rèn)是非本人
private?List<Answer>?answerList;?//?問(wèn)題的回答列表
}

評(píng)論

public?class?Answer?{
????private?String?id;//?當(dāng)前回答的唯一標(biāo)識(shí)
????private?String?nickname;?//?用戶名
????private?String?avator;?//?用戶頭像
????private??Integer?userId;?//?回答的用戶的id
????private??String?Content?;?//?回答的內(nèi)容
????private??Date?time;
????private??boolean?flag?=?false;//?默認(rèn)false.不是本人
????private??Integer?group;?//?分組的標(biāo)記
}

思路

Answer實(shí)體中,并沒(méi)有添加一個(gè)集合用來(lái)存放Answer類(lèi)型的實(shí)體,如果添加上這個(gè)集合的話,確實(shí)想法還不錯(cuò),回復(fù)中有其他人對(duì)自己的回復(fù),天生的樹(shù)形結(jié)構(gòu),但是考慮到前端的渲染的難度加大,放棄了這種方案

問(wèn)題的實(shí)體類(lèi)中維護(hù)了一個(gè)回答的實(shí)體類(lèi)的集合,所有針對(duì)樓主問(wèn)題的回答實(shí)例全部放在這個(gè)集合中, 也包括樓主對(duì)問(wèn)題回答者的回復(fù), 還包含回答者對(duì)問(wèn)題的回復(fù)

于是這樣就僅僅存在兩層,一個(gè)問(wèn)題中維護(hù)著對(duì)這個(gè)問(wèn)題的全部回復(fù),前端渲染的難度大大降低,但是后來(lái)卻來(lái)事了?
用戶查詢一個(gè)問(wèn)題的詳情時(shí),后端如何處理

當(dāng)用戶查詢一個(gè)問(wèn)題的詳情時(shí),后端拿著問(wèn)題的id,去數(shù)據(jù)庫(kù)中將問(wèn)題的實(shí)例取出來(lái),緊接著處理Answer集合,將按照時(shí)間排序的集合按照我們指定的方式分組,再按時(shí)間排序

按什么分組呢?

當(dāng)時(shí)是按照不同的用戶分組, 同一個(gè)用戶的全部評(píng)論,已經(jīng)樓主對(duì)它的回復(fù),以及別人對(duì)它的回復(fù)都放在一起, 所以需要一個(gè)字段,group(我選的用戶id), 專(zhuān)門(mén)存儲(chǔ)分組的標(biāo)志. 組內(nèi)的實(shí)例再按照時(shí)間排序,這樣整體的層次就劃分好了

public?JsonResult?problemDetail(@PathVariable?String?problemId){
????Optional<Problem>?byId?=?problemRepository.findById(problemId);
????if?(!byId.isPresent()){
????????return?JsonResult.fail("您沒(méi)有獲取到詳情頁(yè),請(qǐng)聯(lián)系管理員");
????}
????Problem?problem?=?byId.get();
????if?(problem.getAnswerList().size()>0){
????????????Map<Integer,?List<Answer>>?collect?=?problem.getAnswerList()
????????????.stream().collect(Collectors.groupingBy(Answer::getGroup));
????????????ArrayList<Answer>?list?=?new?ArrayList<>();
????????????collect.forEach((k,v)->{
????????????????list.addAll(v);
????????????});
????????????problem.setAnswerList(list);
????????}
????return?JsonResult.ok("返回詳情頁(yè)"+problem);
}

定位出當(dāng)前用戶的評(píng)論

如果前端想在頁(yè)面的分左右兩部分展示自己的評(píng)論和別人的評(píng)論,就需要一個(gè)標(biāo)記,既然上面都已經(jīng)在遍歷了,多加一個(gè)判斷也無(wú)妨, 拿著前端提交過(guò)來(lái)的用戶id和Answer中的userId比對(duì), 如果相等,就把這個(gè)評(píng)論的flag標(biāo)記為true, 前端根據(jù)這個(gè)標(biāo)記區(qū)分, 從而給用戶更多的權(quán)限,比如刪除自己的評(píng)論

局限性

如果沒(méi)個(gè)問(wèn)題都像網(wǎng)易音樂(lè)那種,上萬(wàn)條評(píng)論,這樣的話,估計(jì)就廢了,雖然使用stream會(huì)快,但是也扛不住量啊, 但是數(shù)量小的話,還是可以接受的, 其實(shí)理想的狀態(tài)是評(píng)論可以以分頁(yè)的形式獲取出來(lái), 感覺(jué)才正宗。

鄭州不孕不育醫(yī)院:http://yyk.39.net/zz3/zonghe/1d427.html


向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI