一,问题描述
【使用 unwind unpack Document 里面的Array中的每个元素,然后使用 group 分组统计,最后使用 sort 对分组结果排序】
从 images.json 文件中导入数据到MongoDB服务器
mongoimport --drop -d test -c images images.json
其中Document的示例如下:
> db.images.find() { "_id" : 3, "height" : 480, "width" : 640, "tags" : [ "kittens", "travel" ] } { "_id" : 1, "height" : 480, "width" : 640, "tags" : [ "cats", "sunrises", "kittens", "travel", "vacation", "work" ] } { "_id" : 0, "height" : 480, "width" : 640, "tags" : [ "dogs", "work" ] } { "_id" : 6, "height" : 480, "width" : 640, "tags" : [ "work" ] } { "_id" : 4, "height" : 480, "width" : 640, "tags" : [ "dogs", "sunrises", "kittens", "travel" ] } { "_id" : 5, "height" : 480, "width" : 640, "tags" : [ "dogs", "cats", "sunrises", "kittens", "work" ] } { "_id" : 7, "height" : 480, "width" : 640, "tags" : [ "dogs", "sunrises" ] } { "_id" : 8, "height" : 480, "width" : 640, "tags" : [ "dogs", "cats", "sunrises", "kittens", "travel" ] }
现在要统计: 所有Document中的 tags 数组里面的每个元素 出现的次数。即:"kittens"出现了多少次?"travel"出现了多少次?"dogs"出现了多少次?……
二,实现步骤
使用MongoDB的Aggregate操作进行实现
①使用 unwind 分解 tags 数组,得到的结果如下:
> db.images.aggregate( ... [ ... {$unwind:"$tags"} ... ]) { "_id" : 3, "height" : 480, "width" : 640, "tags" : "kittens" } { "_id" : 3, "height" : 480, "width" : 640, "tags" : "travel" } { "_id" : 1, "height" : 480, "width" : 640, "tags" : "cats" } { "_id" : 1, "height" : 480, "width" : 640, "tags" : "sunrises" } { "_id" : 1, "height" : 480, "width" : 640, "tags" : "kittens" } { "_id" : 1, "height" : 480, "width" : 640, "tags" : "travel" } { "_id" : 1, "height" : 480, "width" : 640, "tags" : "vacation" } { "_id" : 1, "height" : 480, "width" : 640, "tags" : "work" } { "_id" : 0, "height" : 480, "width" : 640, "tags" : "dogs" } { "_id" : 0, "height" : 480, "width" : 640, "tags" : "work" } { "_id" : 6, "height" : 480, "width" : 640, "tags" : "work" } { "_id" : 4, "height" : 480, "width" : 640, "tags" : "dogs" } { "_id" : 4, "height" : 480, "width" : 640, "tags" : "sunrises" } ..... .....
②将分解后的每个 tag 进行 group 操作
对于group操作而言,_id 指定了 分组 的字段(对哪个字段进行 group by 操作),分组操作之后生成的结果由 num_of_tag 字段标识
> db.images.aggregate( ... [ ... {$unwind:"$tags"}, ... {$group:{_id:"$tags",num_of_tag:{$sum:1}}} ... ] ... ) { "_id" : "dogs", "num_of_tag" : 49921 } { "_id" : "work", "num_of_tag" : 50070 } { "_id" : "vacation", "num_of_tag" : 50036 } { "_id" : "travel", "num_of_tag" : 49977 } { "_id" : "kittens", "num_of_tag" : 49932 } { "_id" : "sunrises", "num_of_tag" : 49887 } { "_id" : "cats", "num_of_tag" : 49772 }
③使用 project 去掉不感兴趣的 _id 字段(其实这里是将 _id 字段名 替换为 tags 字段名)(这一步可忽略)
project操作,_id:0 表示去掉_id 字段;tags:"$_id",将 _id 字段值 使用tags 字段标识;num_of_tag:1 保留 num_of_tag 字段
> db.images.aggregate( [ {$unwind:"$tags"},{$group:{_id:"$tags",num_of_tag:{$sum:1}}},{$project:{_id:0,tags:"$_id",num_of_tag:1}} ]) { "num_of_tag" : 49921, "tags" : "dogs" } { "num_of_tag" : 50070, "tags" : "work" } { "num_of_tag" : 50036, "tags" : "vacation" } { "num_of_tag" : 49977, "tags" : "travel" } { "num_of_tag" : 49932, "tags" : "kittens" } { "num_of_tag" : 49887, "tags" : "sunrises" } { "num_of_tag" : 49772, "tags" : "cats" }
④使用 sort 对 num_of_tag 字段排序
> db.images.aggregate( [ {$unwind:"$tags"},{$group:{_id:"$tags",num_of_tag:{$sum:1}}},{$project:{_id:0,tags:"$_id",num_of_tag:1}},{$sort:{num_of_tag:-1}} ]) { "num_of_tag" : 50070, "tags" : "work" } { "num_of_tag" : 50036, "tags" : "vacation" } { "num_of_tag" : 49977, "tags" : "travel" } { "num_of_tag" : 49932, "tags" : "kittens" } { "num_of_tag" : 49921, "tags" : "dogs" } { "num_of_tag" : 49887, "tags" : "sunrises" } { "num_of_tag" : 49772, "tags" : "cats" }
三,总结
本文是MongoDB University M101课程 For Java Developers中的一次作业。结合Google搜索和MongoDB的官方文档,很容易就能实现MongoDB的各种组合查询。
原文:http://www.cnblogs.com/hapjin/p/7944404.html
时间: 2024-10-31 00:48:31