MongoDB新的資料統計架構介紹

來源:互聯網
上載者:User

目前的MongoDB在進行複雜的資料統計計算時都需要寫MapReduce來實現,包括在SQL中比較常用的group by查詢也需要寫一個reduce才能實現,這是比較麻煩的。在MongoDB2.1中,將會引入一套全新的資料統計計算架構,讓使用者更方便的進行統計操作。

下面我們就來看看幾個新的操作符:

$match

$match的作用是過濾資料,通過設定一個條件,將資料進行篩選過濾,例子:

db.runCommand({ aggregate : "article", pipeline : [    { $match : { author : "dave" } }]});

這相當於將article這個collection中的記錄進行篩選,篩選條件是author屬性值為dave,其作用其實相當於普通的find命令,如:

> db.article.find({ author : "dave" });

所以,那這個命令有什麼用呢?與find不同,find的結果是直接作為最終資料返回,而$match只是pipeline中的一環,它篩選的結果資料可以再進行下一級的統計操作。

$project

$project命令用於設定資料的篩選欄位,就像我們SQL中select需要的欄位一樣。例子:

db.runCommand({ aggregate : "article", pipeline : [    { $match : { author : "dave" } },    { $project : {        _id : 0,author : 1,        tags : 1    }}]});

上面就是將所有author為dave的記錄的author和tags兩個欄位取出來。(_id:0 表示去掉預設會返回的_id欄位)

其實上面這個功能也能用我們平時用的find命令來實現,如:

> db.article.find({ author : "dave" }, { _id : 0, author : 1, tags : 1);
$unwind

$unwind命令很神奇,他可以將某一個為array類型欄位的資料拆分成多條,每一條包含array中的一個屬性。
比如你使用下面命令添加一條記錄:

db.article.save( {    title : "this is your title" ,    author : "dave" ,    posted : new Date(4121381470000) ,    pageViews : 7 ,    tags : [ "fun" , "nasty" ] ,    comments : [        { author :"barbara" , text : "this is interesting" } ,        { author :"jenny" , text : "i like to play pinball", votes: 10 }    ],    other : { bar : 14 }});

這裡面tags欄位就是一個array。下面我們在這個欄位上應用$unwind操作

db.runCommand({ aggregate : "article", pipeline : [    { $unwind : "$tags" }]});

上面命令的意思就是按tags欄位來拆分,此命令執行的結果如下:

{        "result" : [                {                        "_id" : ObjectId("4eeeb5fef09a7c9170df094b"),                        "title" : "this is your title",                        "author" : "dave",                        "posted" : ISODate("2100-08-08T04:11:10Z"),                        "pageViews" : 7,                        "tags" : "fun",                        "comments" : [                                {                                        "author" : "barbara",                                        "text" : "this is interesting"                                },                                {                                        "author" : "jenny",                                        "text" : "i like to play pinball",                                        "votes" : 10                                }                        ],                        "other" : {                                "bar" : 14                        }                },                {                        "_id" : ObjectId("4eeeb5fef09a7c9170df094b"),                        "title" : "this is your title",                        "author" : "dave",                        "posted" : ISODate("2100-08-08T04:11:10Z"),                        "pageViews" : 7,                        "tags" : "nasty",                        "comments" : [                                {                                        "author" : "barbara",                                        "text" : "this is interesting"                                },                                {                                        "author" : "jenny",                                        "text" : "i like to play pinball",                                        "votes" : 10                                }                        ],                        "other" : {                                "bar" : 14                        }                }        ],        "ok" : 1}

我們可以看到,原來的tags欄位是一個包含兩個元素的數組,通過$unwind命令後,被拆分成兩條記錄,每一條記錄的tags欄位是原來數組中的一個元素。

$group

$group命令比較好理解,功能就是按某一個key將key值相同的多條資料群組織成一條。
比如我們使用下面命令再往article這個collection中寫入一條記錄,這時候我們就有兩條記錄了:

db.article.save( {    title : "this is some other title" ,    author : "jane" ,    posted : new Date(978239834000) ,    pageViews : 6 ,    tags : [ "nasty" , "filthy" ] ,    comments : [        { author :"will" , text : "i don't like the color" } ,        { author :"jenny" , text : "can i get that in green?" }    ],    other : { bar : 14 }});

我們可以先用上面的$unwind按tags將記錄拆成多條,然後再將記錄按tags欄位重新組織,將同一個tag對應的所有author放在一個array中。只需要像下面這樣寫:

db.runCommand({ aggregate : "article", pipeline : [    { $unwind : "$tags" },    { $group : {_id : "$tags",        count : { $sum : 1 },authors : { $addToSet : "$author" }    }}]});

這時候你就能得到如下結果了

{        "result" : [                {                        "_id" : "filthy",                        "count" : 1,                        "authors" : [                                "jane"                        ]                },                {                        "_id" : "fun",                        "count" : 1,                        "authors" : [                                "dave"                        ]                },                {                        "_id" : "nasty",                        "count" : 2,                        "authors" : [                                "jane",                                "dave"                        ]                }        ],        "ok" : 1}

上面是2.1版本將會推出的一些新的統計類命令的介紹,在易用性方面它們提供給我們很多便利,但是MongoDB MapReduce的最大硬傷,單個mongod中無法並存執行,貌似還是沒有解決。雖然其命令中採用了pipeline 的組織模式,但是貌似還是完全串列且分降段完成的。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.