在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 問答/數(shù)據(jù)庫/ mongodb聚合查詢?

mongodb聚合查詢?

純前端一枚,之前沒有接觸后臺數(shù)據(jù)庫,現(xiàn)在學習mongodb數(shù)據(jù)庫,遇到這樣的一個情景,建立一個博客的數(shù)據(jù)庫,有這樣一個包含所有文章信息的集合,數(shù)據(jù)偽造如下:

{ "id" : 1, "name" : "one", "tags" : [ "a", "c", "e" ] }
{ "id" : 2, "name" : "two", "tags" : [ "e" ] }
{ "id" : 3, "name" : "three", "tags" : [ "d", "e" ] }
{ "id" : 4, "name" : "four", "tags" : [ "g", "c", "e", "h" ] }
{ "id" : 5, "name" : "five", "tags" : [ "a", "c", "d" ] }

tags 表示這篇文章所屬的標簽類型,現(xiàn)在想要查詢出有多少個不同的標簽類型,每個標簽下有多少條數(shù)據(jù),這個該怎么實現(xiàn)?目前想到的是用 aggregate 中的 $unwind 將 tags 進行拆分,然后再用 $group 進行分組統(tǒng)計,但是具體代碼該怎么寫,或者是有其他更有效的方式,請指教?。?!

回答
編輯回答
吃藕丑

數(shù)據(jù)提取出來后,這就是純統(tǒng)計算法問題了,跟是否前后端無關(guān),當然實現(xiàn)起來也是比較簡單

const list = [
  {"id": 1, "name": "one", "tags": ["a", "c", "e"]},
  {"id": 2, "name": "two", "tags": ["e"]},
  {"id": 3, "name": "three", "tags": ["d", "e"]},
  {"id": 4, "name": "four", "tags": ["g", "c", "e", "h"]},
  {"id": 5, "name": "five", "tags": ["a", "c", "d"]}
];
const result = {
  length: 0 //不同的標簽類型個數(shù)
};
list.forEach(item => {
  item.tags.forEach(tag => {
    if (!result[tag]) {
      result[tag] = {
        name: tag,  //標簽名
        list: []    //包含含有此標簽的id 數(shù)組length就是此標簽下的條目數(shù)
      };
      result.length += 1;
    }
    result[tag].list.push(item.id);
  })
});
console.log(result)
2017年6月30日 07:10
編輯回答
紓惘

這是個很經(jīng)典的統(tǒng)計問題,其實已經(jīng)不是MongoDB特有的范疇了,對于其他數(shù)據(jù)庫來講也是通用的。
你想的辦法本身是沒有問題的,肯定可以通過aggregation的$unwind+$group得到你想要的結(jié)果。問題在于隨著時間推移,參與統(tǒng)計的博客數(shù)量將會越來越多,意味著你的統(tǒng)計語句將越來越慢。問題的關(guān)鍵在于如何限制住每次參與統(tǒng)計的記錄數(shù)。
從另一個角度講,博客一般寫完就很少有改動了,今天統(tǒng)計昨天的所有博客各屬于哪些標簽,跟明天再來統(tǒng)計昨天的得到的結(jié)果應該是一樣的(假設(shè)沒有修改的前提下)。所以每次都進行統(tǒng)計其實是浪費。
基于以上這些考慮,你其實可以每隔一段時間(比如每天)統(tǒng)計一次每個標簽都有多少次出現(xiàn),把它們存起來,在需要時再把這些已經(jīng)聚合過一次的數(shù)據(jù)再次聚合。這種方式稱為預聚合。
大概的方向是這樣,細節(jié)的問題你可以先自己思考一下。

2017年3月27日 06:58