MongoDB聚合统计数组内的某个字段排序

    技术2023-11-03  68

    1:表结构

    { "_id": ObjectId("5efedef1937f00005b003f2b"), "live_id": NumberLong("68391603"), "user_id": NumberLong("840"), "sns_nick": "宝儿cool", "last_comment": NumberLong("1589638938284"), "comment_list": [ { "content": "没拍到3", "timestamp": NumberLong("1589638138283") }, { "content": "我也要", "timestamp": NumberLong("1589638938283") }, { "content": "我也要", "timestamp": NumberLong("1589638938284") } ] } // 2 { "_id": ObjectId("5efedf1a937f00005b003f2c"), "live_id": NumberLong("68391603"), "user_id": NumberLong("1843"), "sns_nick": "小明", "last_comment": NumberLong("1589638938284"), "comment_list": [ { "content": "没拍111到3", "timestamp": NumberLong("1589638138283") }, { "content": "试一试", "timestamp": NumberLong("1589638138283") }, { "content": "试一试3", "timestamp": NumberLong("1589638938283") }, { "content": "我也要", "timestamp": NumberLong("1589638938284") } ] }

    2:查询sql

    db.tb_live_video_comment.aggregate([ { $match: { live_id: 68391603 } }, { $unwind: "$comment_list" }, { $group: { "_id": "$comment_list", count: { $sum: 1 } } }, { $project: { _id: 0, content: "$_id.content", count: 1 } }, { $group: { "_id": "$content", total: { $sum: "$count" } } }, { $sort: { total: - 1 }, }, { $skip: 0 }, { $limit: 10 } ]);

    3:MongoDB新的数据统计框架介绍

    附链接https://blog.csdn.net/terry_water/article/details/43529367

    MongoDB新的数据统计框架介绍

    下面我们就来看看几个新的操作符:

    $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 的组织模式,但是貌似还是完全串行且分降段完成的。  

    Processed: 0.010, SQL: 9