鍍金池/ 問答/數(shù)據(jù)庫/ mongodb 聚合 排序 分頁 數(shù)據(jù)重復(fù)?

mongodb 聚合 排序 分頁 數(shù)據(jù)重復(fù)?

使用aggregate 加上 $sort $skip $limit
當(dāng)$sort值相同時(shí)候 分頁查詢獲取結(jié)果大量重復(fù)

圖片描述

要是不用aggregate 用find 分頁 結(jié)果沒有問題···
如何解決聚合時(shí)候數(shù)據(jù)重復(fù)的問題?

回答
編輯回答
維她命

要這樣理解,你給的排序條件是不充分的。數(shù)據(jù)庫已經(jīng)按照你的要求按{count: -1}完成了排序,但是因?yàn)樗鼈兊闹刀家粯?,不管誰放在前面誰放在后面其實(shí)都沒有違反你的要求,因?yàn)槟愕囊笾皇莄ount的降序而已。從數(shù)據(jù)庫的角度來講,既然你沒有額外的要求,那當(dāng)然是以最高效的方式給你結(jié)果,也就是不管count以外的順序,因?yàn)檫@樣最省資源。
那么何為最高效?這里涉及一些數(shù)據(jù)庫底層的知識(shí)。在單機(jī)上,如果沒有索引支持,數(shù)據(jù)庫會(huì)嘗試遍歷所有數(shù)據(jù),然后做一個(gè)內(nèi)存排序來給你結(jié)果,從節(jié)省資源的角度,顯然這個(gè)排序只排到滿足了count降序?yàn)橹?,其他字段可以說是先到先得。這就造成在count相同時(shí),其他順序是隨機(jī)的。它們可能受到:

  1. 自己在磁盤上的順序影響,因?yàn)檫@會(huì)影響到數(shù)據(jù)庫先遍歷到哪條記錄。并且要注意,每次更新數(shù)據(jù)時(shí)它們?cè)诖疟P上的順序是會(huì)變化的;
  2. 理論上還和數(shù)據(jù)庫使用的排序算法相關(guān)。很遺憾我也沒有關(guān)注這里的排序到底使用什么算法,沒法給你進(jìn)一步的信息;
  3. 在分片集群環(huán)境中,結(jié)果還受到哪個(gè)片先返回?cái)?shù)據(jù)的影響。分片環(huán)境中的排序是先在各個(gè)片排好序,再進(jìn)行一次合并排序;

暫時(shí)想到這些??傊悴恢付?,數(shù)據(jù)庫不保證。
至于解決方案也已經(jīng)很明了了,指定一個(gè)可以完全確定順序的排序條件,比如:

{$sort: {count: -1, _id: 1}}

但是需要理解,這樣會(huì)讓數(shù)據(jù)庫付出額外的努力來保證第二個(gè)排序條件的正確性,在實(shí)際使用場景中你要根據(jù)實(shí)際情況判斷這是不是真的對(duì)你有意義。

最后說句無關(guān)的話,以后提問的時(shí)候建議盡可能用文本貼出相關(guān)的代碼和結(jié)果,而不是截圖。因?yàn)榻貓D雖然方便了你自己,別人在回答問題的時(shí)候如果想用你的代碼或者數(shù)據(jù)做實(shí)驗(yàn)?zāi)蔷拖喈?dāng)麻煩。沒有耐心的人可能直接忽略你的問題,對(duì)你尋找答案也不是件好事。

2018年3月30日 01:05